मेरे उद्देश्यों के लिए, मुझे @ टी-मोटी का विचार पसंद है। भले ही मैंने वर्षों तक "सेल्फ-रेफ़रिंग टाइप" जानकारी का उपयोग किया हो, लेकिन बेस क्लास को संदर्भित करना बाद में करना कठिन है।
उदाहरण के लिए (ऊपर से @Rob Leclerc उदाहरण का उपयोग करके):
public class ChildA: Parent<ChildA>
{
}
public class ChildB: Parent<ChildB>
{
}
इस पैटर्न के साथ काम करना चुनौतीपूर्ण हो सकता है, उदाहरण के लिए; आप फ़ंक्शन कॉल से बेस क्लास कैसे लौटाते हैं?
public Parent<???> GetParent() {}
या कास्टिंग कब टाइप करें?
var c = (Parent<???>) GetSomeParent();
इसलिए, जब मैं कर सकता हूं, तो मैं इसे टालने की कोशिश करता हूं, और जब मुझे इसका उपयोग करना होता है। यदि आपको चाहिए, तो मेरा सुझाव है कि आप इस पैटर्न का पालन करें:
class BaseClass
{
// All non-derived class methods goes here...
// For example:
public int Id { get; private set; }
public string Name { get; private set; }
public void Run() {}
}
class BaseClass<TSelfReferenceType> : BaseClass
{
// All derived class methods goes here...
// For example:
public TSelfReferenceType Foo() {}
public void Bar(TSelfRefenceType obj) {}
}
अब आप (अधिक) आसानी से काम कर सकते हैं BaseClass
। हालाँकि, कई बार, मेरी वर्तमान स्थिति की तरह, जहाँ बेस क्लास के भीतर से व्युत्पन्न वर्ग को उजागर करना आवश्यक नहीं है, और @ M-moty के सुझाव का उपयोग करना सही दृष्टिकोण हो सकता है।
हालाँकि, @ M-moty कोड का उपयोग केवल तब तक काम करता है जब तक कि बेस क्लास में कॉल स्टैक में कोई इंस्टेंस कंस्ट्रक्टर न हो। दुर्भाग्य से मेरे बेस क्लासेज इंस्टेंस कंस्ट्रक्टर्स का उपयोग करते हैं।
इसलिए, यहाँ मेरा एक्सटेंशन तरीका है जो बेस बेस क्लास 'इंस्टेंस' कंस्ट्रक्टर्स को ध्यान में रखता है:
public static class TypeExtensions
{
public static Type GetDrivedType(this Type type, int maxSearchDepth = 10)
{
if (maxSearchDepth < 0)
throw new ArgumentOutOfRangeException(nameof(maxSearchDepth), "Must be greater than 0.");
const int skipFrames = 2; // Skip the call to self, skip the call to the static Ctor.
var stack = new StackTrace();
var maxCount = Math.Min(maxSearchDepth + skipFrames + 1, stack.FrameCount);
var frame = skipFrames;
// Skip all the base class 'instance' ctor calls.
//
while (frame < maxCount)
{
var method = stack.GetFrame(frame).GetMethod();
var declaringType = method.DeclaringType;
if (type.IsAssignableFrom(declaringType))
return declaringType;
frame++;
}
return null;
}
}