2009-09-16 15 views
7

मैं एक फैक्ट्री विधि बनाने की कोशिश कर रहा हूं जो सी # की जेनरिक फीचर का उपयोग करता है।सी # जेनेरिक - टाइप पैरामीटर पर प्रतिबंध

इस कारखाने विधि में मैं इसे कुछ विशिष्ट वर्गों में बाध्य करना चाहता हूं, जिनमें से सभी में डिफ़ॉल्ट कन्स्ट्रक्टर नहीं है।

यहां मेरा उदाहरण है। क्या कोई मुझे बता सकता है कि इसे चलाने के लिए संभव है?

public class AbstractClass { 
    //this abstract class does not have a default constructor, nor its subclasses 
    public AbstractClass(SomeClassName obj) { 
     //use obj for initialization 
    } 
} 

//this factory class should create objects of type T that inherit 
//from AbstractClass and invoke the non-default constructor 
public class FactoryClass { 
    public static T BuildObject<T> (SomeClassName obj) where T: AbstractClass { 
     return new T(obj); //does not work?!?!?! 
    } 
} 


//Edit: ANSWER!!! 
public static T BuildObject<T>(SomeClassUsedForTheConstructor item) where T : SomeAbstractClass { 
return (T) Activator.CreateInstance(typeof (T), item); 
} 

उत्तर

4

Type कक्षा और GetConstructor को देखें। एक बार जब आप ConstructorInfo ऑब्जेक्ट प्राप्त कर लें, तो Invoke Method का उपयोग करें।

var x = typeof(T); 
var t = x.GetConstructor(new[] {obj.GetType()}); 
object u = t.Invoke(<inputs>); 
+0

यही वह है जो मैं उपयोग करता था, लेकिन अब मैं ब्रायन द्वारा वर्णित 'Activator.CreateInstance' का उपयोग करता हूं। –

3

नहीं, आप जो भी करने की कोशिश कर रहे हैं वह अकेले अंतर्निहित जेनेरिक बाधाओं का उपयोग करना संभव नहीं है। नया कीवर्ड केवल आपको सामान्य कन्स्ट्रक्टर रखने के लिए सामान्य प्रकार को बाधित करने की अनुमति देता है।

+0

और केवल तभी टी: नया() परिभाषित किया गया है। –

4

मुझे नहीं लगता कि आप a default constructor अवरोध प्रकार पर बिना सामान्य प्रकार का दृष्टांत कर सकते हैं।

इसके बजाय इंटरफ़ेस IAbstractClass निर्दिष्ट करने पर विचार करें, जैसे कि आपकी फैक्टरी क्लास IClastClass की संपत्ति के रूप में SomeClassName पैरामीटर सेट कर सकती है।

इसके अतिरिक्त, यदि सार क्लास प्रारंभ करने के लिए कुछ क्लासनामनाम उदाहरण आवश्यक है, तो एक खाली डिफ़ॉल्ट कन्स्ट्रक्टर भी मानें, लेकिन IAbstractClass में परिभाषित एक समृद्ध प्रारंभकर्ता विधि। उदाहरण के लिए:

public interface IAbstractClass { void Initialize(SomeClassName obj); } 

इस तरह, आपके स्थिर BuildObject विधि बजाय करता है:

public static T BuildObject<T>(SomeClassName obj) where T: AbstractClass 
{ 
    T newObject = new T(); 
    IAbstractClass ac = newObject as IAbstractClass; 
    ac.Initialize(obj); 
} 
5

मैं अपने जेनरिक प्रकार टी की नई वस्तुओं यह वास्तव में अच्छी तरह से काम करता है बनाने की जरूरत है कि में Activator.CreateInstance(typeof(T)) का उपयोग करना चाहते।

+0

यह .net चट्टानों पॉडकास्ट में जाना चाहिए! जवाब के लिए धन्यवाद। – Pablo

+0

// अंतिम कोड सार्वजनिक स्थिर टी BuildObject (SomeClassUsedForTheConstructor आइटम) जहां टी: SomeAbstractClass { वापसी (टी) Activator.CreateInstance (typeof (टी), आइटम); } – Pablo

+2

यह धीमा है और कोई संकलन-समय जांच नहीं है ... –

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