假设有以下类型定义:
public interface IFoo<T> : IBar<T> {}
public class Foo<T> : IFoo<T> {}
我如何找出类型Foo是否实现了通用接口IBar<T>时,只有manged类型是可用的?
假设有以下类型定义:
public interface IFoo<T> : IBar<T> {}
public class Foo<T> : IFoo<T> {}
我如何找出类型Foo是否实现了通用接口IBar<T>时,只有manged类型是可用的?
当前回答
通过使用tck的答案,也可以用以下LINQ查询完成:
bool isBar = foo.GetType().GetInterfaces().Any(x =>
x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(IBar<>));
其他回答
var genericType = typeof(ITest<>);
Console.WriteLine(typeof(Test).GetInterfaces().Any(x => x.GetGenericTypeDefinition().Equals(genericType))); // prints: "True"
interface ITest<T> { };
class Test : ITest<string> { }
这对我很管用。
首先,公共类Foo: IFoo<T>{}不能编译,因为你需要指定一个类而不是T,但假设你做的事情类似于公共类Foo: IFoo<SomeClass> {}
如果你这样做了
Foo f = new Foo();
IBar<SomeClass> b = f as IBar<SomeClass>;
if(b != null) //derives from IBar<>
Blabla();
您必须检查泛型接口的构造类型。
你必须这样做:
foo is IBar<String>
因为IBar<String>表示构造的类型。你必须这样做的原因是,如果T在检查中是未定义的,编译器不知道你是指IBar<Int32>还是IBar<SomethingElse>。
为了完全解决类型系统,我认为你需要处理递归,例如,IList<T>: ICollection<T>: IEnumerable<T>,否则你不会知道IList<int>最终实现了IEnumerable<>。
/// <summary>Determines whether a type, like IList<int>, implements an open generic interface, like
/// IEnumerable<>. Note that this only checks against *interfaces*.</summary>
/// <param name="candidateType">The type to check.</param>
/// <param name="openGenericInterfaceType">The open generic type which it may impelement</param>
/// <returns>Whether the candidate type implements the open interface.</returns>
public static bool ImplementsOpenGenericInterface(this Type candidateType, Type openGenericInterfaceType)
{
Contract.Requires(candidateType != null);
Contract.Requires(openGenericInterfaceType != null);
return
candidateType.Equals(openGenericInterfaceType) ||
(candidateType.IsGenericType && candidateType.GetGenericTypeDefinition().Equals(openGenericInterfaceType)) ||
candidateType.GetInterfaces().Any(i => i.IsGenericType && i.ImplementsOpenGenericInterface(openGenericInterfaceType));
}
方法检查类型是否继承或实现泛型类型:
public static bool IsTheGenericType(this Type candidateType, Type genericType)
{
return
candidateType != null && genericType != null &&
(candidateType.IsGenericType && candidateType.GetGenericTypeDefinition() == genericType ||
candidateType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == genericType) ||
candidateType.BaseType != null && candidateType.BaseType.IsTheGenericType(genericType));
}