2009-04-30 15 views
22

मेरे पास नीचे कोड है:सी # कंपाइलर: गैर-स्थैतिक संदर्भ में स्थैतिक विधि तक नहीं पहुंच सकता है

public class Anything 
{ 
    public int Data { get; set;} 
} 

public class MyGenericBase<T> 
{ 
    public void InstanceMethod(T data) 
    { 
     // do some job 
    } 

    public static void StaticMethod(T data) 
    { 
     // do some job 
    } 

    // others members... 
} 

public sealed class UsefulController : MyGenericBase<Anything> 
{ 
    public void ProxyToStaticMethod() 
    { 
     StaticMethod(null); 
    } 

    // others non derived members... 
} 

public class Container 
{ 
    public UsefulController B { get; set; } 
} 

public class Demo 
{ 
    public static void Test() 
    { 
     var c = new Container(); 
     c.B.InstanceMethod(null); // Works as expected. 
     c.B.StaticMethod(null);  // Doesn't work. 
            // Static method call on object rather than type. 
            // How to get the static method on the base type ? 
     c.B.ProxyToStaticMethod(); // Works as expected. 
    } 
} 

संकलक बहुत गुस्सा है ... मैं त्रुटि संदेश समझता हूं लेकिन मुझे नहीं पता कि इसे कैसे हल किया जाए। मैं अपनी स्थिर विधि कॉल करने के लिए किसी ऑब्जेक्ट की बजाय एक प्रकार प्राप्त करने का प्रयास कर रहा था, लेकिन मुझे इसे सही तरीके से करने का तरीका नहीं मिला। इसके अलावा इसके परिणामस्वरूप कुछ भी सुरुचिपूर्ण नहीं है।

असल में, जेनेरिकबेस एक ढांचे से एक वर्ग है जिसमें बहुत से स्थिर तरीके और कुछ उदाहरण विधियां हैं। नियंत्रक इस वर्ग को टाइप कर रहा है और इसे विस्तारित कर रहा है।

कंटेनर तार्किक संबंधित नियंत्रकों का एक समूह है।

दिलचस्प बात: इस कोड का जावा संस्करण सही ढंग से संकलित करता है, लेकिन एक चेतावनी के साथ। निष्पादन भी सही है।

क्या यह हल करने के लिए एक डिज़ाइन पैटर्न मौजूद है?

आपके इनपुट के लिए धन्यवाद!


मुझे आपके उत्तर के लिए धन्यवाद, इस समस्या से छुटकारा पाने का एक तरीका मिला। ऐसा लगता है, लेकिन मैं यह नहीं बता सकता कि साइड इफेक्ट्स सही तरीके से जानते हैं या नहीं।

 public class GenericBase<T> : MyGenericBase<T> 
{ 
    // Create instance calls here for every base static method. 
} 

public sealed class UsefulController : GenericBase<Anything> 
{ 
    // others non derived members... 
} 

उत्तर

26

किसी विशिष्ट विधि पर एक विशिष्ट स्थिर विधि को कॉल करने के लिए एक स्थिर विधि को कॉल करने के लिए संकलित किया जाएगा। दूसरे शब्दों में, यह निर्धारित करने के लिए कि कौन सी स्थिर विधि कॉल करने के लिए बी की सामग्री का उपयोग नहीं किया जाएगा।

तो कॉल को संकलित समय पर हल करने योग्य होना चाहिए, इसलिए यह शिकायत करता है, क्योंकि यह सब जानते हैं, आप उस संपत्ति की सामग्री को कई ठोस प्रकारों से प्रतिस्थापित कर सकते हैं, जिसका अर्थ यह होगा कि स्थैतिक विधि को कॉल करना होगा इन वर्गों में से किसी एक में एक स्थिर विधि के लिए हल किया जाना है।

कंपाइलर में वर्चुअल या अमूर्त स्थैतिक विधि जैसी कोई चीज़ नहीं है, इसलिए एक के लिए आप गारंटी नहीं दे सकते कि उन सभी वर्गों में यह स्थिर विधि है। और चूंकि कॉल संकलन समय पर हल करने योग्य है, यह इस तरह काम नहीं करेगा।

जैसा कि आपने देखा है, ऑब्जेक्ट की एक इंस्टेंस विधि को कॉल कर सकते हैं, जो बदले में स्थिर विधि को कॉल करता है। यह उपरोक्त नियमों को अमान्य नहीं करता है क्योंकि जब संकलक उस आवृत्ति विधि को संकलित करता है, तो कौन सी स्थैतिक विधि कॉल करेगी वह स्थिर और ज्ञात है।

+0

बहुत ही निर्देशक, धन्यवाद!नीचे दिए गए उत्तरों को पढ़ना, मैं एक संभावित समाधान के बारे में सोच रहा हूं। टिप्पणी करने के लिए स्वतंत्र महसूस करें। –

+0

सब के बाद, उन्हें कुछ भी नहीं – BlackTigerX

2

आप इसे सी # में नहीं कर सकते हैं। आप इसे वीबी.नेट और जावा में कर सकते हैं, लेकिन ईमानदारी से, यह वास्तव में समझ में नहीं आता है। यह आपको static विधि में पॉलिमॉर्फिज्म की झूठी भावना देता है, जो किसी भी माध्यम से वास्तविक नहीं है। चूंकि यह बहुरूप नहीं है, इसलिए संपूर्ण विधि कॉल संकलन समय (स्थिर रूप से) पर जाना जाता है और आप सीधे कक्षा के नाम के साथ कॉल का उल्लेख कर सकते हैं।

9

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

MyGenericBase<Anything>.StaticMethod(null); 
+0

धन्यवाद के लिए स्टेटिक कहा जाता है! मैंने पहले ही यह देखा है। मैं कंटेनर के माध्यम से इन कॉल करने के लिए एक रास्ता तलाश रहा हूँ। आप बेस बेस को किसी अन्य आधार पर प्राप्त करने के बारे में क्या सोचेंगे, जिसमें आवृत्ति विधियों को आवृत्ति कॉल शामिल होगा, फिर उससे प्राप्त करने के लिए? –

1

आप उन में से एक कर सकते हैं:

UsefulController.StaticMethod(null); 
MyGenericBase<Anything>.StaticMethod(null); 

उदाहरण का उपयोग करते हुए संभव के रूप में पहले से ही दूसरों से नहीं समझाया है।

+0

धन्यवाद! मैंने पहले ही यह देखा है। मैं कंटेनर के माध्यम से इन कॉल करने के लिए एक रास्ता तलाश रहा हूँ। आप बेस बेस को किसी अन्य आधार पर प्राप्त करने के बारे में क्या सोचेंगे, जिसमें आवृत्ति विधियों को आवृत्ति कॉल शामिल होगा, फिर उससे प्राप्त करने के लिए? –

+0

यदि आपको लगता है कि आपको इस उदाहरण कॉल की "आवश्यकता" है, तो बस अपनी प्रॉक्सी विधि जोड़ें। मेरी सलाह सिर्फ एपीआई को साफ और स्पष्ट रखने की कोशिश करने के लिए है। – Lucero

+0

जैसा कि मैं सीधे कक्षा का उपयोग कर स्थिर सदस्यों को कॉल नहीं कर सकता, ऐसा लगता है कि यह अभी के लिए एकमात्र समाधान है। मैं एपीआई को यथासंभव स्वच्छ रखने के लिए सहमत हूं। –

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