क्या परीक्षण करने का कोई तरीका है यदि 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)falsetruecnull
यदि 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 के उत्तर का उपयोग करें।