2011-08-12 10 views
7

मैं इस तरह एक बड़ा स्विच बयान के साथ इस विधि है:स्टेटिक शब्दकोश उदाहरण तरीकों के प्रतिनिधियों युक्त

public bool ExecuteCommand(string command, string args) 
{ 
    bool result = false; 
    switch (command) 
    { 
     case "command1": result = Method1(args); break; 
     case "command2": result = Method2(args); break; 
     // etc. 
    } 
    return result; 
} 
private bool Method1(string args) {...} 

अब मैं Func<> प्रतिनिधियों का एक शब्दकोश के साथ इस जगह इतना है कि मैं स्विच बयान समाप्त कर सकते हैं के बारे में सोचा:

private Dictionary<string, Func<string, bool>> _commands = new ...; 
public MyClass() 
{ 
    _commands.Add("command1", Method1); 
    // etc: 
} 
public bool ExecuteCommand(string command, string args) 
{ 
    return _commands[command](args); 
} 

समस्या मैं इस के साथ देखते हैं, कि एक नया शब्दकोश instantiated और MyClass के प्रत्येक नया उदाहरण के साथ से भर जाता है है।

क्या किसी भी तरह से उस शब्दकोश को बनाने के लिए संभव है (उदाहरण के तरीकों के प्रतिनिधियों को एक स्थिर सदस्य), जो स्थिर कन्स्ट्रक्टर में केवल एक बार शुरू किया जाएगा?

उदा। कुछ इस तरह (काम नहीं करता है):

private static Dictionary<string, Func<string, bool>> _commands = new ...; 
static MyClass() 
{ 
    // the following line will result in a compiler error: 
    // error CS0120: An object reference is required for the non-static field, 
    // method, or property 'MyClass.Method1(string, string)' 
    _commands.Add("command1", MyClass.Method1); 
} 
+2

यह क्यों काम नहीं करता है, त्रुटि क्या है? हो सकता है कि अगर आप एक स्थिर गेटर में आलसी शुरू करें, तो यह काम करता है? इस तरह मैं इसे आमतौर पर सिंगलटन आदि के लिए जाता हूं, – ewernli

+0

@ewernli: संकलक त्रुटि के साथ प्रश्न अद्यतन किया। (ध्यान दें: मुझे आवृत्ति विधियों को कॉल करने की आवश्यकता है, स्थैतिक तरीकों से नहीं)। – M4N

+0

आपको जो त्रुटि मिल रही है वह 'MyClass.Method1' को आपके शब्दकोश में' Func 'के रूप में जोड़ने का प्रयास संदर्भित कर रहा है। शब्दकोश की स्थैतिक स्थापना नहीं है। 'MyClass' को 'विधि 1' विधि एक स्थैतिक विधि है? आपको जो त्रुटि मिल रही है, वह इंगित करती है कि यह नहीं है और संकलक यह अपेक्षा करता है। – Clayton

उत्तर

18

आप स्थिर निर्माता में यह प्रारंभ कर सकते हैं - लेकिन क्योंकि मैं आप मान लें कि आपके, MyClass के उदाहरण है, जो नहीं हो सकता है कि आप क्या चाहते बनाने की आवश्यकता होगी उदाहरण के संदर्भ में "Execute पर कॉल करने के लिए" आदेश को निष्पादित करना चाहते हैं। एक बनाने के द्वारा

class MyClass 
{ 
    static Dictionary<string, Func<MyClass, string, bool>> commands 
     = new Dictionary<string, Func<MyClass, string, bool>> 
    { 
     { "Foo", (@this, x) => @this.Foo(x) }, 
     { "Bar", (@this, y) => @this.Bar(y) } 
    }; 

    public bool Execute(string command, string value) 
    { 
     return commands[command](this, value); 
    } 

    public bool Foo(string x) 
    { 
     return x.Length > 3; 
    } 

    public bool Bar(string x) 
    { 
     return x == ""; 
    } 
} 

सिद्धांत रूप में मेरा मानना ​​है कि यह लैम्ब्डा अभिव्यक्ति के बिना संभव होना चाहिए ":

वैकल्पिक रूप से, आप MyClass का एक उदाहरण के रूप में अच्छी तरह से प्रतिनिधियों जो लेने के साथ शब्दकोश पॉप्युलेट कर सकते हैं, इस तरह खुला प्रतिनिधि ", लेकिन प्रतिबिंब का उपयोग करके इसे थोड़ा और काम करने की आवश्यकता होगी। यदि आपको कुरूपता और छोटे अतिरिक्त संकेत के प्रदर्शन दंड पर ध्यान नहीं दिया जाता है, तो मुझे लगता है कि इस दृष्टिकोण को काफी अच्छी तरह से काम करना चाहिए।

+0

हां, मैं वही उदाहरण पर आदेश को निष्पादित करना चाहता हूं जहां निष्पादन() को बुलाया गया था - तो आपका वैकल्पिक समाधान ऐसा लगता है कि मुझे क्या चाहिए। धन्यवाद। – M4N

+0

यह एक पुराना धागा है, लेकिन मैं कचरा संग्रह पर प्रतिनिधियों के साथ स्थिर शब्दकोश के प्रभाव को जानना चाहता हूं। मेरा अनुमान है क्योंकि यह स्थैतिक शब्दकोश है, इसे अंततः पीढ़ी 2 में पदोन्नत किया जाएगा और शायद वहां रहें और कचरा इकट्ठा न हो। आपके विचार कृपया – AlwaysAProgrammer

+0

@AlwaysAProgrammer: मुझे नहीं लगता कि प्रतिनिधि इसके लिए विशेष रूप से प्रासंगिक क्यों हैं। हां, प्रतिनिधि हमेशा के लिए मौजूद रहेगा ...लेकिन यह इस मामले में इरादा है ... –

संबंधित मुद्दे