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.IsAssignableFrom () 이라는 메서드가 있습니다 .
T상속 / 구현 여부를 확인하려면 다음을 수행하십시오 Employee.
typeof(Employee).IsAssignableFrom(typeof(T));
.NET Core를 대상으로하는 경우 메서드가 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: 샘플은 다음과해야하므로 클래스 만, 그것의 유일한 인수로 소속 카테고리를 허용typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
클래스에 제약 조건을 사용할 수 있습니다.
MyClass<T> where T : Employee
http://msdn.microsoft.com/en-us/library/d5x73970.aspx를 살펴보십시오 .
올바른 구문은 다음과 같습니다.
typeof(Employee).IsAssignableFrom(typeof(T))
반환 값 :
true경우c전류와Type같은 유형을 표시, 또는 현재이 경우Type의 상속 계층 구조에c, 또는 현재는 경우Type인interface것을c구현하는 경우, 또는c제네릭 형식 매개 변수이며, 전류Type의 제약 중 하나를 나타냅니다c, 또는 만약이c값의 형식을 나타내고, 전류Type나타낸다Nullable<c>(Nullable(Of c)Visual Basic에서).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
- b1 = c1
- 실패 : c2 = b1
- b1 = c2
IsAssignableFrom이 다른 사람들이 말한 것처럼 가장 좋은 방법이지만 클래스가 다른 클래스에서 상속되는지 확인하기 만하면되는 경우 typeof(T).BaseType == typeof(SomeClass)에도 작업을 수행합니다.
SomeClass에서 직접 파생되지 않는 한 작동합니다 BaseClass.
객체 o가 클래스를 상속 하는지 또는 인터페이스를 구현 하는지 알 수있는 또 다른 방법 은 is및 as연산자 를 사용하는 것 입니다.
객체가 클래스를 상속하는지 또는 인터페이스를 구현하는지 만 알고 싶다면 is연산자는 부울 결과를 반환합니다.
bool isCompatibleType = (o is BaseType || o is IInterface);
테스트 후 상속 된 클래스 또는 구현 된 인터페이스를 사용하려는 경우 as연산자는 상속 된 클래스 또는 구현 된 인터페이스에 대한 참조를 반환하거나 호환되지 않는 경우 null을 반환하여 안전한 캐스트를 수행합니다.
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의 대답을 사용하십시오.