यह संभव है
tl; dr - यदि आप चाहते हैं तो आप सेटर के साथ केवल-प्राप्त विधि को ओवरराइड कर सकते हैं। यह मूल रूप से सिर्फ:
एक ऐसी new
संपत्ति बनाएं जिसमें एक get
और एक set
ही नाम का उपयोग किया गया हो।
यदि आप कुछ और नहीं करते हैं, तो पुरानी get
पद्धति को तब भी कहा जाएगा जब व्युत्पन्न वर्ग को उसके आधार प्रकार के माध्यम से बुलाया जाता है। इसे ठीक करने के लिए, एक abstract
मध्यवर्ती परत जोड़ें जो override
पुरानी get
पद्धति का उपयोग करता है और इसे नई get
विधि के परिणाम को वापस करने के लिए मजबूर करता है ।
यह हमें संपत्तियों को ओवरराइड करने में सक्षम बनाता है get
/ set
भले ही उनकी आधार परिभाषा में कोई कमी हो।
बोनस के रूप में, आप चाहें तो रिटर्न प्रकार भी बदल सकते हैं।
यदि आधार की परिभाषा get
-only थी, तो आप अधिक व्युत्पन्न रिटर्न प्रकार का उपयोग कर सकते हैं।
यदि आधार की परिभाषा थी set
, तो आप हमें कम व्युत्पन्न रिटर्न प्रकार दे सकते हैं।
यदि आधार परिभाषा पहले से ही थी get
/ है set
, तो:
सभी मामलों में, आप चाहें तो एक ही रिटर्न प्रकार रख सकते हैं। नीचे दिए गए उदाहरण सादगी के लिए समान रिटर्न प्रकार का उपयोग करते हैं।
स्थिति: पहले से मौजूद मौजूदा get
संपत्ति
आपके पास कुछ वर्ग संरचना है जिसे आप संशोधित नहीं कर सकते हैं। शायद यह सिर्फ एक वर्ग है, या यह पहले से मौजूद वंशानुक्रम का पेड़ है। जो भी हो, आप set
एक संपत्ति में एक विधि जोड़ना चाहते हैं, लेकिन नहीं कर सकते।
public abstract class A // Pre-existing class; can't modify
{
public abstract int X { get; } // You want a setter, but can't add it.
}
public class B : A // Pre-existing class; can't modify
{
public override int X { get { return 0; } }
}
समस्या: नहीं कर सकते के साथ -only /override
get
get
set
आप override
एक get
/ set
संपत्ति के साथ चाहते हैं, लेकिन यह संकलन नहीं करेगा।
public class C : B
{
private int _x;
public override int X
{
get { return _x; }
set { _x = value; } // Won't compile
}
}
समाधान: एक abstract
मध्यवर्ती परत का उपयोग करें
जब आप सीधे override
एक get
/ set
संपत्ति के साथ नहीं कर सकते , तो आप कर सकते हैं :
एक ही नाम से एक new
get
/ set
संपत्ति बनाएँ ।
override
संगति सुनिश्चित get
करने के लिए नई get
विधि के लिए एक सहायक के साथ पुरानी विधि ।
तो, पहले आप abstract
मध्यवर्ती परत लिखते हैं :
public abstract class C : B
{
// Seal off the old getter. From now on, its only job
// is to alias the new getter in the base classes.
public sealed override int X { get { return this.XGetter; } }
protected abstract int XGetter { get; }
}
फिर, आप उस वर्ग को लिखते हैं जो पहले संकलित नहीं किया गया था। यह इस बार संकलित करेगा क्योंकि आप वास्तव में override
' get
एन-प्रॉपर्टी ' नहीं कर रहे हैं; इसके बजाय, आप इसे new
कीवर्ड का उपयोग करके बदल रहे हैं ।
public class D : C
{
private int _x;
public new virtual int X { get { return this._x; } set { this._x = value; } }
// Ensure base classes (A,B,C) use the new get method.
protected sealed override int XGetter { get { return this.X; } }
}
परिणाम: सब कुछ काम करता है!
जाहिर है, इस काम के लिए के रूप में इरादा है D
।
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
test.X = 7;
Print(test.X); // Prints "7", as intended.
सब कुछ अभी भी काम करता है, जब D
इसका आधार कक्षाओं में से एक के रूप में देखा जाता है, जैसे A
या B
। लेकिन, यह क्यों काम करता है इसका कारण थोड़ा कम स्पष्ट हो सकता है।
var test = new D() as B;
//test.X = 7; // This won't compile, because test looks like a B,
// and B still doesn't provide a visible setter.
हालाँकि, बेस क्लास की परिभाषा get
अभी भी अंततः व्युत्पन्न वर्ग की परिभाषा से ओवरराइड है get
, इसलिए यह अभी भी पूरी तरह से सुसंगत है।
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
var baseTest = test as A;
Print(test.X); // Prints "7", as intended.
विचार-विमर्श
यह विधि आपको -only गुणों के लिए set
तरीकों को जोड़ने की अनुमति देती है get
। आप इसका उपयोग सामान की तरह करने के लिए भी कर सकते हैं:
किसी भी संपत्ति को एक get
एकल वर्ग में बदलें , चाहे वह set
, या get
-और- set
संपत्ति, चाहे वह किसी आधार वर्ग में हो।
व्युत्पन्न वर्गों में एक विधि का वापसी प्रकार बदलें।
मुख्य कमियां यह हैं कि करने के लिए अधिक कोडिंग है और abstract class
विरासत के पेड़ में एक अतिरिक्त है। यह उन कंस्ट्रक्टरों के लिए थोड़ा कष्टप्रद हो सकता है जो पैरामीटर लेते हैं क्योंकि उन्हें मध्यवर्ती परत में कॉपी / पेस्ट करना पड़ता है।