2016-12-12 9 views
8

से असाइन किए जाने योग्य प्रकार का प्रतिनिधित्व करता है, मैं मुख्य रूप से जावा प्रोग्रामर हूं, इसलिए यह उन लोगों में से एक होगा जो जावा से समतुल्य सी # प्रश्नों में से हैं। तो, जावा में, आप एक कक्षा प्रकार तर्क संकलन समय पर तो जैसे, एक निश्चित सुपर वर्ग का विस्तार करने को नियंत्रित कर सकते हैं:सुनिश्चित करें कि टाइप इंस्टेंस कुछ वर्ग

public <T extends BaseClass> void foo(Class<T> type) { 
    ... 
} 

और यहां तक ​​कि

public <T extends BaseClass> T foo(Class<T> type) { 
    ... 
} 

तुम भी कई इंटरफेस श्रृंखला कर सकते हैं :

public <T extends BaseClass & BaseInterface1 & BaseInterface2> void foo(Class<T> type) { 
    ... 
} 

यह सी # में कैसे किया जाता है? मुझे पता है कि आप "जहां टी: बेस क्लास" का उपयोग कर सकते हैं, लेकिन यह केवल तभी लागू होता है जब आपके पास एक उदाहरण टी हो। जब आपके पास केवल एक उदाहरण उदाहरण होता है तो क्या होगा?

संपादित करें:

सभा # 1 (base.dll):

स्पष्टीकरण के लिए, यहाँ मैं क्या करना चाहते हैं क्या है

abstract class BaseClass { 
    abstract void Foo(); 
} 

सभा # 2 (sub1.dll, संदर्भ base.dll):

class SubClass1 : BaseClass { 
    void Foo() { 
     // some code 
    } 
} 

सभा # 3 (sub2.dll, संदर्भ base.dll):

class SubClass2 : BaseClass { 
    void Foo() { 
     // some other code 
    } 
} 

सभा # 4 (main.dll, संदर्भ base.dll):

class BaseClassUtil { 
    static void CallFoo(Type<T> type) where T : BaseClass { 
     T instance = (T)Activator.CreateInstance(type); 
     instance.Foo(); 
    } 
} 

public static void Main(String[] args) { 
    // Here I use 'args' to get a class type, 
    // possibly loading it dynamically from a DLL 

    Type<? : BaseClass> type = LoadFromDll(args); // Loaded from DLL 

    BaseClassUtil.CallFoo(type); 
} 

तो, इस उदाहरण में, मुझे परवाह नहीं है क्या वर्ग 'प्रकार' चर का प्रतिनिधित्व करता है, जब तक कि यह बेस क्लास से लिया गया है, इसलिए एक बार जब मैं एक उदाहरण बना देता हूं, तो Foo() को कॉल कर सकता हूं।

वे हिस्सों जो सी # कोड (लेकिन बल्कि कुछ जावा मॉकअप) नहीं हैं वे "जेनेरिक" टाइप क्लासेस हैं: < टी> टाइप करें और < टाइप करें? : बेस क्लास>।

उत्तर

2

नहीं में होना चाहिए है, वहाँ संकलन समय है कि एक Type एक सामान्य प्रकार के लिए आबंटित हो पर लागू करने के लिए कोई रास्ता नहीं है।अगर मैं सही ढंग से समझ, क्या आप चाहते हैं:

void Foo<T>(Type type) { ... } //compile time error if an instace typed `type` is not assignable to `T`. 

जिसका मतलब है:

void Foo<IFormattable>(typeof(string)); //ok 
void Foo<IDisposable>(typeof(string)); //compile time error 

जाहिर कार्यावधि में यह trival है, लेकिन भाषा संकलन समय पर इसके लिए कोई भी समर्थन हासिल है।

2

मैं क्या समझ में आ आप के बारे में generic type constraint

public void Foo<T>(Type type) where T:BaseClass, BaseInterface1, BaseInterface2 
{ 
    //your code 
} 

एक अन्य लेख में बात कर रहे यहाँ से: Constraints on Type Parameters (C# Programming Guide)

When you define a generic class, you can apply restrictions to the kinds of types that client code can use for type arguments when it instantiates your class. If client code tries to instantiate your class by using a type that is not allowed by a constraint, the result is a compile-time error.

संपादित करें:

यहाँ अपने उदाहरण। अब यदि आप बेस क्लास और उसके व्युत्पन्न कक्षाओं से कुछ अलग के साथ BaseClassUtil.CallFoo<T> पर कॉल करने का प्रयास करते हैं तो आपको एक संकलन त्रुटि प्राप्त होगी। यहां full example in dotNetFiddle। तो मुश्किल हिस्सा अपनी कक्षा के प्रतिबंध util वर्ग

public static void Main(string[] args) 
    { 
     //so your LoadFromDll method should return Type. Type doesn't have generic implementation ! 
     Type type = typeof(SubClass1); 

     BaseClassUtil.CallFoo<BaseClass>(type); 

     Type type2 = typeof(SubClass2); 
     //you can write BaseClassUtil.CallFoo<SubClass2>(type2); if you want 
     BaseClassUtil.CallFoo<BaseClass>(type2); 
    } 

    public class BaseClassUtil 
    { 
     public static void CallFoo<T>(Type type) where T : BaseClass 
     { 
      T instance = (T)Activator.CreateInstance(type); 
      instance.Foo(); 
     } 
    } 
    public class TestClass 
    { 
     public int ID { get; set; } 

    } 

    public abstract class BaseClass 
    { 
     public abstract void Foo(); 
    } 

    public class SubClass1 : BaseClass 
    { 
     public override void Foo() 
     { 
      Console.WriteLine("SubClass 1"); 
     } 
    } 

    public class SubClass2 : BaseClass 
    { 
     public override void Foo() 
     { 
      Console.WriteLine("SubClass 2"); 
     } 

    } 
+0

आपके उत्तर के लिए धन्यवाद, लेकिन मुझे यकीन नहीं है कि यह मेरी आवश्यकताओं के अनुरूप है। समस्याग्रस्त हिस्सा "कक्षा प्रकार" भाग है - मुझे नहीं लगता कि यह वैध सी # वाक्यविन्यास है - और यह पूरी समस्या है। अगर यह था, तो यह निश्चित रूप से मेरी समस्या का समाधान होगा। लेकिन मुझे यकीन है कि यह नहीं है ... – milin

+0

@ मिलिन मैंने आपको थोड़ा उदाहरण लिखा है, मुझे आशा है कि यह आपके संदेहों को साफ़ करेगा – mybirthname

+0

मैंने एक उदाहरण जोड़ा जो मैं करना चाहता हूं - मुझे लगता है कि मेरी व्याख्या पर्याप्त स्पष्ट नहीं थी क्योंकि आपका उदाहरण चिंतित है जेनेरिक उदाहरणों के बारे में, और मुझे सामान्य प्रकार के उदाहरणों में समस्या है। – milin

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