क्या परीक्षण करने का कोई तरीका है यदि T विरासत में मिला / क्लास / इंटरफ़ेस लागू करता है?
private void MyGenericClass<T> ()
{
if(T ... inherits or implements some class/interface
}
क्या परीक्षण करने का कोई तरीका है यदि T विरासत में मिला / क्लास / इंटरफ़ेस लागू करता है?
private void MyGenericClass<T> ()
{
if(T ... inherits or implements some class/interface
}
जवाबों:
Type.sAssignableFrom () नामक एक विधि है ।
यह जाँचने के लिए कि क्या T
विरासत / उपकरण हैं Employee
:
typeof(Employee).IsAssignableFrom(typeof(T));
यदि आप .NET कोर को लक्षित कर रहे हैं, तो विधि TypeInfo में चली गई है:
typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
T inherits U
वास्तव में अनुवाद करता है typeof(T).IsAssignableFrom(typeof(U))
।
T
किसी अन्य प्रकार के लिए विवश किया जाता है TOther
, तो जब निष्पादित किया जाता है, typeof(T)
तो वास्तव में मूल्यांकन करेंगे typeof(TOther)
और न कि T
आप जिस प्रकार से वास्तव में उत्तीर्ण हुए थे, और उस मामले में, typeof(SomeInterface).IsAssignableFrom(typeof(T))
विफल हो जाएगा (यह मानते हुए TOther
भी लागू नहीं होता है SomeInterface
), भले ही आपके ठोस प्रकार ने कार्यान्वित किया हो SomeInterface
।
IsAssignableFrom
की TypeInfo
कक्षा केवल, यह केवल तर्क के रूप में स्वीकार करता है TypeInfo तो नमूना निम्न होना चाहिए:typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
आप कक्षा में बाधाओं का उपयोग कर सकते हैं।
MyClass<T> where T : Employee
Http://msdn.microsoft.com/en-us/library/d5x73970.aspx पर एक नज़र डालें
यदि आप संकलन के दौरान जांच करना चाहते हैं: यदि वांछित इंटरफ़ेस / वर्ग को लागू T
नहीं करता है तो त्रुटि , आप निम्नलिखित बाधा का उपयोग कर सकते हैं
public void MyRestrictedMethod<T>() where T : MyInterface1, MyInterface2, MySuperClass
{
//Code of my method here, clean without any check for type constraints.
}
मुझे आशा है कि वह मदद करेंगे।
सही सिंटैक्स है
typeof(Employee).IsAssignableFrom(typeof(T))
वापसी मान:
true
यदिc
और वर्तमानType
एक ही प्रकार का प्रतिनिधित्व करते हैं, या यदि वर्तमानType
विरासत की पदानुक्रम में हैc
, या यदि वर्तमानType
एक हैinterface
किc
लागू होता है, या यदिc
एक सामान्य प्रकार का पैरामीटर है और वर्तमानType
एक बाधा का प्रतिनिधित्व करता हैc
, या यदिc
एक मान प्रकार का प्रतिनिधित्व करता है और वर्तमान ( विजुअल बेसिक में) काType
प्रतिनिधित्व करता है । यदि इनमें से कोई भी स्थिति नहीं है , या यदि है ।Nullable<c>
Nullable(Of c)
false
true
c
null
यदि Employee IsAssignableFrom T
फिर से T
विरासत में मिला है Employee
।
उपयोगितायें
typeof(T).IsAssignableFrom(typeof(Employee))
true
तभी लौटता है जब या तो
T
और Employee
उसी प्रकार का प्रतिनिधित्व करते हैं; या,Employee
से विरासत में मिला है T
।यह कुछ मामलों में उपयोग करने का इरादा हो सकता है , लेकिन मूल प्रश्न (और अधिक सामान्य उपयोग) के लिए, यह निर्धारित करने के लिए कि T
विरासत class
/ कुछ का interface
उपयोग कब लागू होता है :
typeof(Employee).IsAssignableFrom(typeof(T))
वास्तव में सभी का मतलब क्या है:
typeof(BaseType).IsAssignableFrom(typeof(DerivedType)) // => true
आप सचमुच सकता है, क्योंकि से आवंटित एक का एक उदाहरण DerivedType
एक का एक उदाहरण के लिए BaseType
:
DerivedType childInstance = new DerivedType();
BaseType parentInstance = childInstance; // okay, assigning base from derived
childInstance = (DerivedType) parentInstance; // not okay, assigning derived from base
कब
public class BaseType {}
public class DerivedType : BaseType {}
और कुछ ठोस उदाहरण यदि आपको अपने सिर को उसके चारों ओर लपेटने में परेशानी हो रही है:
(LinqPad के माध्यम से, इसलिए HorizontalRun
और Dump
)
void Main()
{
// http://stackoverflow.com/questions/10718364/check-if-t-inherits-or-implements-a-class-interface
var b1 = new BaseClass1();
var c1 = new ChildClass1();
var c2 = new ChildClass2();
var nb = new nobase();
Util.HorizontalRun(
"baseclass->baseclass,child1->baseclass,baseclass->child1,child2->baseclass,baseclass->child2,nobase->baseclass,baseclass->nobase",
b1.IsAssignableFrom(typeof(BaseClass1)),
c1.IsAssignableFrom(typeof(BaseClass1)),
b1.IsAssignableFrom(typeof(ChildClass1)),
c2.IsAssignableFrom(typeof(BaseClass1)),
b1.IsAssignableFrom(typeof(ChildClass2)),
nb.IsAssignableFrom(typeof(BaseClass1)),
b1.IsAssignableFrom(typeof(nobase))
).Dump("Results");
var results = new List<string>();
string test;
test = "c1 = b1";
try {
c1 = (ChildClass1) b1;
results.Add(test);
} catch { results.Add("FAIL: " + test); }
test = "b1 = c1";
try {
b1 = c1;
results.Add(test);
} catch { results.Add("FAIL: " + test); }
test = "c2 = b1";
try {
c2 = (ChildClass2) b1;
results.Add(test);
} catch { results.Add("FAIL: " + test); }
test = "b1 = c2";
try {
b1 = c2;
results.Add(test);
} catch { results.Add("FAIL: " + test); }
results.Dump();
}
// Define other methods and classes here
public static class exts {
public static bool IsAssignableFrom<T>(this T entity, Type baseType) {
return typeof(T).IsAssignableFrom(baseType);
}
}
class BaseClass1 {
public int id;
}
class ChildClass1 : BaseClass1 {
public string name;
}
class ChildClass2 : ChildClass1 {
public string descr;
}
class nobase {
public int id;
public string name;
public string descr;
}
baseclass-> baseclass
सच
child1-> baseclass
असत्य
baseclass-> child1
सच
child2-> baseclass
असत्य
baseclass-> child2
सच
nobase-> baseclass
असत्य
baseclass-> nobase
असत्य
तथा
- विफल: c1 = b1
- बी 1 = सी 1
- विफल: c2 = b1
- बी 1 = सी 2
हालांकि IsAssignableFrom अन्य लोगों द्वारा बताए गए तरीके से सबसे अच्छा तरीका है, अगर आपको केवल यह जांचने की आवश्यकता है कि क्या एक वर्ग दूसरे से विरासत में मिला typeof(T).BaseType == typeof(SomeClass)
है, काम भी करता है।
SomeClass
सीधे से प्राप्त नहीं किया जाता है BaseClass
।
वैकल्पिक तरीके यह बताने के लिए कि क्या कोई ऑब्जेक्ट o
एक वर्ग को विरासत में मिला है या एक इंटरफ़ेस लागू करना है is
और as
ऑपरेटरों का उपयोग करना है ।
यदि आप केवल यह जानना चाहते हैं कि क्या कोई ऑब्जेक्ट एक वर्ग को विरासत में मिला है या एक इंटरफ़ेस को लागू करता है, तो is
ऑपरेटर एक बूलियन परिणाम देगा:
bool isCompatibleType = (o is BaseType || o is IInterface);
यदि आप अपने परीक्षण के बाद विरासत में मिले वर्ग या कार्यान्वित किए गए इंटरफ़ेस का उपयोग करना चाहते हैं, तो as
ऑपरेटर एक सुरक्षित कलाकारों का प्रदर्शन करेगा, जो विरासत में मिला वर्ग या कार्यान्वित इंटरफ़ेस का संदर्भ लौटाएगा यदि संगत या अशक्त न हो तो:
BaseType b = o as BaseType; // Null if d does not inherit from BaseType.
IInterface i = o as IInterface; // Null if d does not implement IInterface.
यदि आपके पास केवल प्रकार है T
, तो @ nikeee के उत्तर का उपयोग करें।