2011-02-03 11 views
9

मैं निम्नलिखित त्रुटि मिल रही है:क्या मैं एक इंटरफ़ेस को कार्यान्वित कर सकता हूं जिसमें एक प्रकार की संपत्ति है जो कि बच्चे के प्रकार की है जो इंटरफ़ेस द्वारा आवश्यक है?

ClassName.PropertyName cannot implement IClassType.PropertyName because it does not have the matching return type of IBasePropertyType

अब, कोड के लिए:

public class ClassName : IClassType 
{ 
    public IChildPropertyType PropertyName { get; set; } 
} 

public interface IClassType 
{ 
    public IBasePropertyType PropertyName { get; set; } 
} 

public interface IBasePropertyType 
{ 
    // some methods 
} 

public interface IChildPropertyType : IBasePropertyType 
{ 
    // some methods 
} 

वहाँ मैं क्या प्रयास कर रहा हूँ करने के लिए एक तरीका है? मुझे पता है कि यह मुद्दा सह/contravariance के साथ है, लेकिन मुझे यह पता लगाने के लिए प्रतीत नहीं होता है कि यह कैसे करें।

+0

तो सवाल क्या है? – Victor

+0

@ विक्टर: क्या इंटरफ़ेस को कार्यान्वित करने का कोई तरीका है, लेकिन इंटरफ़ेस में परिभाषित संपत्ति प्रकार के लिए बच्चे के प्रकार की संपत्ति है? –

उत्तर

7

दिए गए इंटरफ़ेस को लागू करने के लिए, आपके पास एक ही रिटर्न प्रकार होना चाहिए।

  1. अपने इंटरफेस सामान्य
  2. स्पष्ट इंटरफ़ेस को लागू करना: हालांकि, वहाँ संभावित काम arounds के एक जोड़े जीवन को आसान बनाने के लिए कर रहे हैं।

आप IClassType, सामान्य की तरह तो करते हैं:

public interface IClassType<T> where T : IBasePropertyType 
{ 
    public T PropertyName { get; set; } 
} 

... तो आप इस इंटरफेस विभिन्न संपत्ति प्रकार का उपयोग कर लागू कर सकते हैं:

public class ClassName : IClassType<IChildPropertyType> 
{ 
    public IChildPropertyType PropertyName { get; set; } 
} 

एक अन्य विकल्प छोड़ने के लिए होगा अपने इंटरफेस गैर सामान्य है, लेकिन एक सामान्य आधार प्रकार है कि स्पष्ट रूप से इंटरफेस को लागू करता है:

public class ClassBase<T> : IClassType 
    where T : IChildPropertyType 
{ 
    IBasePropertyType IClassType.PropertyName { 
     get {return PropertyName;} 
     set {PropertyName = (IChildPropertyType)value;} 
    } 
    T PropertyName {get;set;} 
} 

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

+0

मैंने सामान्य मार्ग का प्रयास किया है, लेकिन अभी तक सभी टुकड़ों को एक साथ नहीं मिला है (या नहीं मैं यहां नहीं होगा)। धन्यवाद, और मैं कोड नमूने देखने के लिए तत्पर हूं जो इसे काम करता है। –

+0

@ मार्क एवेनियस: वहां वे हैं। मुझे बताओ तुम क्या सोचते हो। – StriplingWarrior

+0

ने मेरा उत्तर हटा दिया क्योंकि आपका बहुत बेहतर –

4

आप सही हैं कि इसे कॉन्वर्सिस के साथ करना है; विशेष रूप से यह आभासी विधि वापसी प्रकार सहप्रसरण, जो सहप्रसरण कि सी # भाषा का समर्थन करता है का एक प्रकार नहीं है के साथ क्या करना है।

ध्यान दें कि भले ही यह किया है, प्रणाली आप का वर्णन सुरक्षित टाइप नहीं है। मान लीजिए हमने:

interface IAnimal {} 
interface IGiraffe : IAnimal {} 
interface ITiger: IAnimal {} 
class Tiger : ITiger {} 
interface IHaveAnAnimal { IAnimal Animal { get; set; } } 
class C : IHaveAnAnimal 
{ 
    public IGiraffe Animal { get; set; } 
} 
... 
IHaveAnAnimal x = new C(); 
x.Animal = new Tiger(); // Uh oh. We just put a Tiger into a property of type IGiraffe. 

यहां तक ​​कि अगर सहप्रसरण कानूनी बिल्कुल, सहप्रसरण इस तरह का कानूनी नहीं होगा थे; कॉन्वर्सेंस कानूनी होने के लिए आपको कोई सेटटर होना होगा।

मान लीजिए तो आप कोई सेटर किया:

interface IAnimal {} 
interface IGiraffe : IAnimal {} 
interface ITiger: IAnimal {} 
class Tiger : ITiger {} 
interface IHaveAnAnimal { IAnimal Animal { get; } } 
class C : IHaveAnAnimal 
{ 
    public IGiraffe Animal { get; } 
} 

दुर्भाग्य से यह अभी भी कानूनी नहीं है। लेकिन आप यह कर सकते हैं:

class C : IHaveAnAnimal 
{ 
    IAnimal IHaveAnAnimal.Animal { get { return this.Animal; } } 
    public IGiraffe Animal { get; } 
} 

अब जब सी सी के रूप में प्रयोग किया जाता है, पशु एक जिराफ़ देता है, और जब एक एक IHaveAnAnimal इस्तेमाल किया, यह एक IAnimal देता है।

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

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