2009-09-28 11 views
19

मैं केवल आधार सारणी कक्षा से किसी दिए गए संपत्ति पर सी # गेटर के कार्यान्वयन को मजबूर करना चाहता हूं। व्युत्पन्न कक्षाएं, यदि वे चाहें, तो उस संपत्ति के लिए स्थिर रूप से बाध्य प्रकार के सार्वजनिक उपयोग के लिए एक सेटटर भी प्रदान करें।संपत्ति पढ़ने/लिखने के लिए अमूर्त रीडोनली संपत्ति को ओवरराइड करें

को देखते हुए निम्नलिखित सार वर्ग:

public abstract class Base 
{ 
    public abstract int Property { get; } 
} 

अगर मैं एक व्युत्पन्न वर्ग है कि यह भी एक सेटर को लागू करता है चाहता हूँ, मैं भोलेपन की कोशिश कर सकते:

public class Derived : Base 
{ 
    public override int Property 
    { 
     get { return field; } 
     set { field = value; } // Error : Nothing to override. 
    } 

    private int field; 
} 

लेकिन तब मैं के बाद से मैं एक वाक्य रचना त्रुटि मिलती है गैर मौजूदा सेटर को ओवरराइड करने का प्रयास करें। मैंने कुछ अन्य तरीकों की कोशिश की जैसे कि बेस सेटर निजी और इस तरह की घोषणा करना और मैं अभी भी मुझे ऐसा करने से रोकने वाली सभी प्रकार की त्रुटियों पर ठोकर खा रहा हूं। ऐसा करने का एक तरीका होना चाहिए क्योंकि यह किसी भी बेस क्लास अनुबंध को तोड़ता नहीं है।

संयोग से, यह इंटरफेस के साथ किया जा सकता है, लेकिन मुझे वास्तव में उस डिफ़ॉल्ट कार्यान्वयन की आवश्यकता है।

मैं उस स्थिति में इतनी बार ठोकर खा रहा था, मैं सोच रहा था कि ऐसा करने के लिए एक छिपी हुई सी # वाक्यविन्यास चाल थी, अन्यथा मैं इसके साथ रहूंगा और मैन्युअल सेटप्रोपर्टी() विधि को कार्यान्वित करूँगा।

+0

पार लिंक: http://stackoverflow.com/questions/2243886/make-a-read-only-property-writable-in-the-derived-class – Mikhail

उत्तर

11

आप इसे सीधे नहीं कर सकते हैं, क्योंकि आप उसी प्रकार के हस्ताक्षर के साथ new और override नहीं कर सकते हैं; दो विकल्प हैं - अगर आप आधार वर्ग को नियंत्रित, एक दूसरा संपत्ति जोड़ें:

public abstract class Base 
{ 
    public int Property { get { return PropertyImpl; } } 
    protected abstract int PropertyImpl {get;} 
} 
public class Derived : Base 
{ 
    public new int Property {get;set;} 
    protected override int PropertyImpl 
    { 
     get { return Property; } 
    } 
} 

वरना आप वर्ग पदानुक्रम में एक अतिरिक्त स्तर को पेश कर सकते हैं:

public abstract class Base 
{ 
    public abstract int Property { get; } 
} 
public abstract class SecondBase : Base 
{ 
    public sealed override int Property 
    { 
     get { return PropertyImpl; } 
    } 
    protected abstract int PropertyImpl { get; } 
} 
public class Derived : SecondBase 
{ 
    public new int Property { get; set; } 

    protected override int PropertyImpl 
    { 
     get { return Property; } 
    } 
} 
+0

आपका समाधान दिलचस्प हैं, मैं विचार करना होगा उन पर थोड़ा सा। – Coincoin

+1

आपका समाधान यह है कि चीज़ के सबसे नज़दीक क्या है। लेकिन मुझे नहीं लगता कि व्युत्पन्न वर्ग को एक्रोबेटिक्स करने के लिए मजबूर किए बिना ऐसा करना संभव है। – Coincoin

2

क्या की तरह कुछ के बारे में:

public abstract class Base 
{ 
    public virtual int Property 
    { 
     get { return this.GetProperty(); } 
     set { } 
    } 

    protected abstract int GetProperty(); 
} 
+1

किसी भी विरासतकर्ता को अब दोनों को ओवरराइड करना है - थोड़ा अनावश्यक? –

+0

केवल संपत्ति को ओवरराइड करते समय। अन्यथा, आभासी संपत्ति के बिना जो वास्तव में एक स्वीकार्य विकल्प हो सकता है। – Coincoin

+1

यदि आप संपत्ति को ओवरराइड नहीं करते हैं, तो सेट का उद्देश्य बहुत असामान्य है। –

1

क्या यह आपकी आवश्यकताओं के अनुरूप होगा?

public abstract class TheBase 
{ 
    public int Value 
    { 
     get; 
     protected set; 
    } 
} 
public class TheDerived : TheBase 
{ 
    public new int Value 
    { 
     get { return base.Value; } 
     set { base.Value = value; } 
    } 
} 

virtual हटा दिया गया था, लेकिन अभी भी आधार मूल्य मूल्य के लिए केवल भंडारण है। तो यह '5' दिखाना चाहिए। और संकलक के बारे में b.Value = 4;

TheDerived d = new TheDerived(); 
d.Value = 5; 
TheBase b = d; 
//b.Value = 4; // uncomment for compiler error 
cout << "b.Value == " << b.Value << endl; 

-Jesse

1

उपद्रव चाहिए मैं एक ऐसी ही आवश्यकता है, जहां मैं एक अंतरफलक की जरूरत दो शिथिल संबंधित वर्गों के बीच आम सॉर्टिंग कार्यक्षमता साझा करने में सक्षम होना ही था। उनमें से एक को केवल पढ़ने के लिए ऑर्डर प्रॉपर्टी थी और दूसरे के पास एक पठन-लिखने वाली ऑर्डर प्रॉपर्टी थी, लेकिन मुझे दोनों वर्गों से संपत्ति को पढ़ने के लिए एक तरीका चाहिए।

यह पता चला है कि यह व्युत्पन्न इंटरफ़ेस में केवल-पढ़ने योग्य मूल्य को छुपाकर किया जा सकता है। यहाँ देखें कि मैंने यह कैसे किया।

interface ISortable 
{ 
    int Order { get; } 
} 

interface ISortableClass2 
    : ISortable 
{ 
    // This hides the read-only member of ISortable but still satisfies the contract 
    new int Order { get; set; } 
} 

class SortableClass1 
    : ISortable 
{ 
    private readonly int order; 

    public SortableClass1(int order) 
    { 
     this.order = order; 
    } 

    #region ISortable Members 

    public int Order 
    { 
     get { return this.order; } 
    } 

    #endregion 
} 

class SortableClass2 
    : ISortableClass2 
{ 
    #region ISortableClass2 Members 

     public int Order { get; set; } 

    #endregion 
} 

class RunSorting 
{ 
    public static void Run() 
    { 
     // Test SortableClass1 
     var list1 = new List<SortableClass1>(); 

     list1.Add(new SortableClass1(6)); 
     list1.Add(new SortableClass1(1)); 
     list1.Add(new SortableClass1(5)); 
     list1.Add(new SortableClass1(2)); 
     list1.Add(new SortableClass1(4)); 
     list1.Add(new SortableClass1(3)); 

     var sorted1 = SortObjects(list1); 

     foreach (var item in sorted1) 
     { 
      Console.WriteLine("SortableClass1 order " + item.Order); 
     } 

     // Test SortableClass2 
     var list2 = new List<SortableClass2>(); 

     list2.Add(new SortableClass2() { Order = 6 }); 
     list2.Add(new SortableClass2() { Order = 2 }); 
     list2.Add(new SortableClass2() { Order = 5 }); 
     list2.Add(new SortableClass2() { Order = 1 }); 
     list2.Add(new SortableClass2() { Order = 4 }); 
     list2.Add(new SortableClass2() { Order = 3 }); 

     var sorted2 = SortObjects(list2); 

     foreach (var item in sorted2) 
     { 
      Console.WriteLine("SortableClass2 order " + item.Order); 
     } 
    } 

    private static IEnumerable<T> SortObjects<T>(IList<T> objectsToSort) where T : ISortable 
    { 
     if (objectsToSort.Any(x => x.Order != 0)) 
     { 
      return objectsToSort.OrderBy(x => x.Order); 
     } 

     return objectsToSort; 
    } 
} 
संबंधित मुद्दे