आप अभी भी पांच साल के बारे में एक accpted जवाब बाद में की जरूरत नहीं है के लिए, मुझे इसे आजमाइए (फिर) जाने ..
मैंने कभी एक समाधान के रूप Curiously Recurring Template Pattern के बारे में सोचा है, लेकिन आप के बाद से ' विरासत के लिए BaseClass
खोलेंगे यह एक अच्छा विचार नहीं होगा। क्यों आप बेहतर समझने के लिए Mr. Lippert's blogpost पर एक नज़र रखना चाहते हैं।
समाधान 1: आप रजिस्टर नहीं है, मैं पहचान नहीं पा रहे ..
public abstract class BaseClass {
protected static void Register<U>(String identifier) where U : BaseClass {
m_identities.Add(typeof(U).GetHashCode(), identifier);
}
public static String GetIdentifier<U>() where U : BaseClass {
var t = typeof(U);
var identifier = default(String);
RuntimeHelpers.RunClassConstructor(t.TypeHandle);
m_identities.TryGetValue(t.GetHashCode(), out identifier);
return identifier;
}
static Dictionary<int, String> m_identities = new Dictionary<int, String> { };
}
public class DerivedClassA:BaseClass {
static DerivedClassA() {
BaseClass.Register<DerivedClassA>("12dc2490-065d-449e-a199-6ba051c93622");
}
}
public class DerivedClassB:BaseClass {
static DerivedClassB() {
BaseClass.Register<DerivedClassB>("9745e24a-c38b-417d-a44d-0717e10e3b96");
}
}
परीक्षण:
Debug.Print("{0}", BaseClass.GetIdentifier<DerivedClassA>());
Debug.Print("{0}", BaseClass.GetIdentifier<DerivedClassB>());
यह है प्रकार शुरू करने के माध्यम से एक अपेक्षाकृत सरल पैटर्न आर। Register
विधि केवल व्युत्पन्न कक्षा के संपर्क में है; और GetIdentifier
और Register
दोनों विधियों को BaseClass
से व्युत्पन्न एक प्रकार तर्क के साथ बुलाया जाता है। यद्यपि हम व्युत्पन्न कक्षाओं को कुछ भी ओवरराइड करने के लिए बाध्य नहीं करते हैं, अगर यह स्वयं पंजीकृत नहीं होता है, तो GetIdentifier
इसे पहचानता नहीं है और null
देता है।
समाधान 2: इससे पहले कि आप अपनी पहचान दिखाने के लिए, मैं तुम्हें एक डिफ़ॉल्ट खरीदते हैं। जो भी आप सोचते हैं, मैं विश्वास करता हूं - जब तक कोई अस्पष्टता न हो।
public abstract class BaseClass {
public abstract String Identifier {
get;
}
public static Type GetDerivedClass(String identifier) {
return m_aliases[identifier];
}
public static String GetIdentifier(Type t) {
var value = default(String);
if(t.IsSubclassOf(typeof(BaseClass))) {
var key = t.GetHashCode();
if(!m_identities.TryGetValue(key, out value)) {
value=""+key;
m_aliases.Add(value, t);
m_identities[key]=value;
}
}
return value;
}
static void UpdateAlias(BaseClass x) {
var t = x.GetType();
var value = x.Identifier;
m_aliases.Add(value, t);
m_identities[t.GetHashCode()]=value;
}
protected BaseClass() {
BaseClass.UpdateAlias(this);
}
static Dictionary<String, Type> m_aliases = new Dictionary<String, Type> { };
static Dictionary<int, String> m_identities = new Dictionary<int, String> { };
}
public class DerivedClassA:BaseClass {
public override String Identifier {
get {
return "just text";
}
}
}
public class DerivedClassB:BaseClass {
public override String Identifier {
get {
return "just text";
}
}
}
और परीक्षण:
public static void TestMethod() {
var idBeforeInstantiation = BaseClass.GetIdentifier(typeof(DerivedClassA));
var y = new DerivedClassA { };
var idAfterInstantiation = BaseClass.GetIdentifier(typeof(DerivedClassA));
Debug.Print("B's: {0}", BaseClass.GetIdentifier(typeof(DerivedClassB)));
Debug.Print("A's after: {0}", idAfterInstantiation);
Debug.Print("A's before: {0}", idBeforeInstantiation);
Debug.Print("A's present: {0}", BaseClass.GetIdentifier(typeof(DerivedClassA)));
var type1 = BaseClass.GetDerivedClass(idAfterInstantiation);
var type2 = BaseClass.GetDerivedClass(idBeforeInstantiation);
Debug.Print("{0}", type2==type1); // true
Debug.Print("{0}", type2==typeof(DerivedClassA)); // true
Debug.Print("{0}", type1==typeof(DerivedClassA)); // true
var typeB=BaseClass.GetDerivedClass(BaseClass.GetIdentifier(typeof(DerivedClassB)));
var x = new DerivedClassB { }; // confilct
}
जाहिर है यह एक अधिक जटिल समाधान है।जैसा कि आप idBeforeInstantiation
और idAfterInstantiation
देख सकते हैं, हालांकि, वे DerivedClassA
के लिए मान्य पहचानकर्ता हैं। m_identities
में प्रत्येक व्युत्पन्न वर्ग के लिए अंतिम अद्यतन पहचानकर्ता शामिल है और m_aliases
व्युत्पन्न कक्षाओं के लिए सभी पहचानकर्ता उपनाम शामिल होंगे। चूंकि वर्चुअल और स्थिर वर्तमान में भाषा की एक विशेषता नहीं है (शायद कभी नहीं ..), अगर हम ओवरराइड करना चाहते हैं तो हमें कुछ कामकाज के माध्यम से इसे करना होगा। यदि आप समाधान 2 का चयन करेंगे, तो हो सकता है कि आप व्युत्पन्न कक्षाओं को एक ही प्रकार के लिए विभिन्न उपनामों को प्रदान करने से रोकने के लिए UpdateAlias
पर अपने आप को लागू करना चाहें, हालांकि वे सभी वैध होंगे। परीक्षण में अंतिम बयान जानबूझकर पहचानकर्ताओं के संघर्ष का प्रदर्शन करने के लिए रखा जाता है।
इन दो समाधान के लिए ध्यान से की आपके विचार व्युत्पन्न वर्ग का दृष्टांत के लिए नहीं के लिए तैयार कर रहे हैं, उनमें से कोई भी कि आवश्यकता है।
स्रोत
2018-01-09 22:37:33
स्थिर सदस्यों को ओवरडोड नहीं किया जा सकता है (या यह "ओवरराइड" है?) मेरी खराब अंग्रेजी क्षमा करें = ( –
जैसा कि आपने कहा था, सी # इसका समर्थन नहीं करता है, इसलिए आप इसे कार्यान्वित नहीं कर सकते हैं। – Servy
वैसे भी, आप इसके लिए क्या चाहते हैं? 'गुण' का उपयोग करके हासिल किया जा सकता है। –