2009-02-18 23 views
5

मेरे पास एक इंटरफ़ेस है, और दो कक्षाएं जो इंटरफ़ेस लागू करती हैं। कक्षाओं में सामान्य प्रकार होते हैं। मैं एक वर्ग के दूसरे भाग से क्लोन करना चाहता हूं।सी # जेनेरिक कॉपी कन्स्ट्रक्टर

interface IFoo 
{ 
    // stuff 
} 

class Foo<T> : IFoo 
{ 
    // foo stuff 
    // ifoo implementation 
} 

class Bar<T> : IFoo 
{ 
    // bar stuff 
    // ifoo implementation 
} 

मेरे पास एक फू है और बार पसंद है। बार में एक प्रतिलिपि बनाने वाला IFoo का पैरामीटर ले रहा है। मैं एक विस्तार विधि बनाया क्लोन लागू करने के लिए:

public static Bar<T> Clone<T>(this IFoo foo) 
{ 
    return new Bar<T>(foo); 
} 

विधि कॉलिंग प्रकार की आवश्यकता है:

someFoo.Clone<T> ... 

वहाँ जब विस्तार विधि को संशोधित करके विधि बुला प्रकार की घोषणा न करने का एक रास्ता है , या किसी अन्य तरीके से, उदाहरण को इसके अंतर्निहित प्रकार की देखभाल किए बिना बस पारित करने की अनुमति देने के लिए?

अद्यतन यहां बताया गया है कि स्थिति का बेहतर वर्णन करने के लिए इसका उपयोग कैसे किया जा रहा है।

एक विधि में मैं एक संग्रह को पुन: सक्रिय करता हूं और IFoo की गणना वापस करता हूं। विधि में मैं स्रोत संग्रह की विशेषता को देखता हूं और फू के प्रकार का निर्धारण करता हूं।

IFoo foo = null; 

string type = element.Attribute("Type").Value; 
switch (type) 
{ 
    case "int": 
     foo = new Foo<int>(); 
     break; 

    case "string": 
     foo = new Foo<string>(); 
     break; 

    // etc 
} 
// other stuff 

yield return foo; 

कॉलिंग विधि की एक सूची है। बाद में मैं इस सूची से अलग-अलग वस्तुओं का उपयोग करने के लिए चुनता हूं, जिस बिंदु पर मुझे एक फू के बजाय बार पसंद है। सूची से चयन करते समय उदाहरण IFoo प्रकार के होते हैं, क्योंकि इन्हें केवल "इस IFoo foo" के लिए एक्सटेंशन विधियां दिखाई देती हैं। मैं इफू को एक फू में नहीं डालना चाहता, जिसके लिए टी के प्रकार को फिर से घोषित करने की आवश्यकता होगी। मैं सिर्फ फू को यह बताना चाहता हूं कि यह क्या है। क्या यह संभव है?

+0

शायद मुझे कुछ याद आ रही है, लेकिन यदि यो यू एक्सटेंशन फ़ंक्शन एक आईफू लेता है, अगर इसे फू टाइप करने के लिए इसे बार में "क्लोन" करना कैसा लगता है? –

+0

मुझे केवल इस बात की परवाह है कि आईएफयू गुणों में मूल्यों को फू से बार में कॉपी किया जा रहा है। – blu

उत्तर

0

विल प्रेरणा ?: How would you improve this shallow copying class?

मूलतः यह एक सामान्य प्रतिबिंब आधारित संपत्ति नकल विधि है के लिए यह सहायता। कोशिश करके देखो।

0

यदि यह आपके परिदृश्य के लिए काम करता है तो आपके पास IFoo<T> हो सकता है। इसके अलावा यदि आपको विशिष्ट एक्सटेंशन विधियों को ध्यान में रखना नहीं है, तो आप केवल Foo<T> प्राप्त कर सकते हैं। आपको वास्तव में कुछ ऐसा करने की आवश्यकता है जो टी को संदर्भित करे ताकि संकलक उपयुक्त प्रकार का अनुमान लगा सके।

0

आप अपनी गहरी प्रतिलिपि क्लोन पर पूरा नियंत्रण की जरूरत है, इस पद्धति बहुत अच्छा है:

public class FooBase 
{ 
    private int x; 

    public FooBase() { /* standard contructor */ } 

    protected FooBase(FooBase clone) 
    { 
     this.x = clone.x; 
    } 

    public FooBase Clone() { return new FooBase(this); } 
} 

public class Foo : FooBase 
{ 
    private int y; 

    public Foo() { /* standard contructor */ } 

    protected Foo(Foo clone) : base(clone) 
    { 
     this.y = clone.y; 
    } 

    public Foo Clone() { return new Foo(this); } 
} 

क्लोनिंग के लिए संरक्षित contructor परिभाषित करें - तो व्युत्पन्न वर्ग आधार वर्ग में मूल्यों को क्लोन कर सकते हैं। यह पैटर्न हाथ से लिखा जाना चाहिए (या अच्छे टी 4 टेम्पलेट की मदद से उत्पन्न) लेकिन गहरे क्लोनिंग के लिए बहुत अच्छा है।

अद्यतन: मुझे लगता है कि मैंने इस प्रश्न को गलत समझा है और पहले ही क्लोनिंग लागू कर दी है। फ्रेडी सही है - कंपाइलर को पता होना चाहिए कि किस प्रकार का अनुमान लगाया जाना चाहिए और यह आईफू प्रकार से नहीं कर सकता है। यह में यह कर सकता है (यह Foo < टी> foo) हालांकि।

0

ऐसे

public static Bar<T> Clone<T>(this Foo<T> foo) 
{ 
    return new Bar<T>(foo); 
} 

इस तरह के रूप में विधि को परिभाषित करने का प्रयास करें, पैरामीटर एक सामान्य प्रकार के लिए होता है और संकलक से प्रकार का निष्कर्ष निकालते के लिए एक स्रोत होगा।

2

तो तुम सब कुछ ठीक है, लेकिन आप इसे डाल करने के लिए वहाँ स्पष्ट रूप से होने के बजाय निहित होने के लिए की

someFoo.Clone<int>() 

आप पूर्णांक चाहते

someFoo.Clone() 

बजाय सिंटैक्स का उपयोग करने में सक्षम होना चाहते ?

कारण आप अपने कोड उदाहरण में ऐसा नहीं कर सकते हैं कि IFoo सामान्य प्रकार टी को संदर्भित नहीं करता है जिसे आपको Bar<T> बनाने के लिए आवश्यक है।

मेरा सुझाव है कि आप वास्तव में एक और इंटरफेस की जरूरत है: IFoo<T>

अगर आपको लगता है कि था, और अपने विस्तार विधि इस प्रकार है:

public static Bar<T> Clone<T>(this IFoo<T> foo) 
{ 
    return new Bar<T>(foo); 
} 

तो फिर तुम

IFoo<int> someFoo = new Foo<int>(); 
Bar<int> someBar = someFoo.Clone(); 
का उपयोग कर कोई समस्या नहीं होगा

आशा है कि

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