通过反射判断 class 是否实现了一个接口
Find out if class implements an interface thru reflection
我在 c# 中有以下 class:
public class WorkOrderStatus : ICustomEnum<WorkOrderStatus>
{
}
在运行时,我需要弄清楚以下 class 的 属性 是否实现了自定义接口。
public class WorkOrder{
public WorkOrderStatus Status {get;set;}
}
所以我尝试执行以下操作(使用反射来解决):
prop.PropertyType.GetInterfaces().Contains(typeof(ICustomEnum));
但这表示 ICustomEnum 需要通用类型。所以我尝试执行以下操作,但它不起作用:
var type = prop.GetType();
prop.PropertyType.GetInterfaces().Contains(typeof(ICustomEnum<typeof(type)>));
说 type 是一个变量,但像类型一样使用
[编辑 1]
我稍后需要能够创建 WorkOrderStatus
或任何其他 class 的实例,通过反射实现此接口,如下所示:
var instance = (ICustomEnum<WorkOrderStatus|SomeOtherStatus...>)Activator.CreateInstance(prop.PropertyType);
您可以使用 GetGenericTypeDefinition
来达到这个目的。例如,
propertyInfo.PropertyType
.GetInterfaces()
.Where(x => x.IsGenericType)
.Any(i => i.GetGenericTypeDefinition() == typeof(ICustomEnum<>));
要检索实现特定通用接口的类型的所有属性,您可以
var properties = typeof(WorkOrder).GetProperties();
var result = properties.Where(property=>property.PropertyType
.GetInterfaces()
.Where(x => x.IsGenericType)
.Any(i => i.GetGenericTypeDefinition() == typeof(ICustomEnum<>)));
用IsAssignableTo
做起来很简单:
Type propertyType = typeof(WorkOrder).GetProperty("Status").PropertyType;
Type interfaceType = typeof(ICustomEnum<>).MakeGenericType(propertyType);
bool implements = propertyType.IsAssignableTo(interfaceType);
而且,您可能会发现 typeof(ICustomEnum<>).MakeGenericType(propertyType);
直接在您的代码中解决了您的问题。
所以你写 typeof(ICustomEnum<>).MakeGenericType(type)
而不是 typeof(ICustomEnum<typeof(type)>)
。
以下是如何使用反射调用方法,以便您可以从 运行 时类型移回编译时类型。
void Main()
{
Type propertyType = typeof(WorkOrder).GetProperty("Status").PropertyType;
Type interfaceType = typeof(ICustomEnum<>).MakeGenericType(propertyType);
bool implements = propertyType.IsAssignableTo(interfaceType);
if (implements)
{
object propertyInstance = Activator.CreateInstance(propertyType);
var method =
this
.GetType()
.GetMethod("SomeMethod", BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(propertyType);
method.Invoke(this, new[] { propertyInstance });
}
}
private void SomeMethod<T>(ICustomEnum<T> customEnum)
{
Console.WriteLine($"Success with {typeof(T)}");
}
输出如下:
Success with WorkOrderStatus
这是运行以上内容所需的杂项代码:
public class WorkOrderStatus : ICustomEnum<WorkOrderStatus> { }
public interface ICustomEnum<T> { }
public class WorkOrder
{
public WorkOrderStatus Status { get; set; }
}
我在 c# 中有以下 class:
public class WorkOrderStatus : ICustomEnum<WorkOrderStatus>
{
}
在运行时,我需要弄清楚以下 class 的 属性 是否实现了自定义接口。
public class WorkOrder{
public WorkOrderStatus Status {get;set;}
}
所以我尝试执行以下操作(使用反射来解决):
prop.PropertyType.GetInterfaces().Contains(typeof(ICustomEnum));
但这表示 ICustomEnum 需要通用类型。所以我尝试执行以下操作,但它不起作用:
var type = prop.GetType();
prop.PropertyType.GetInterfaces().Contains(typeof(ICustomEnum<typeof(type)>));
说 type 是一个变量,但像类型一样使用
[编辑 1]
我稍后需要能够创建 WorkOrderStatus
或任何其他 class 的实例,通过反射实现此接口,如下所示:
var instance = (ICustomEnum<WorkOrderStatus|SomeOtherStatus...>)Activator.CreateInstance(prop.PropertyType);
您可以使用 GetGenericTypeDefinition
来达到这个目的。例如,
propertyInfo.PropertyType
.GetInterfaces()
.Where(x => x.IsGenericType)
.Any(i => i.GetGenericTypeDefinition() == typeof(ICustomEnum<>));
要检索实现特定通用接口的类型的所有属性,您可以
var properties = typeof(WorkOrder).GetProperties();
var result = properties.Where(property=>property.PropertyType
.GetInterfaces()
.Where(x => x.IsGenericType)
.Any(i => i.GetGenericTypeDefinition() == typeof(ICustomEnum<>)));
用IsAssignableTo
做起来很简单:
Type propertyType = typeof(WorkOrder).GetProperty("Status").PropertyType;
Type interfaceType = typeof(ICustomEnum<>).MakeGenericType(propertyType);
bool implements = propertyType.IsAssignableTo(interfaceType);
而且,您可能会发现 typeof(ICustomEnum<>).MakeGenericType(propertyType);
直接在您的代码中解决了您的问题。
所以你写 typeof(ICustomEnum<>).MakeGenericType(type)
而不是 typeof(ICustomEnum<typeof(type)>)
。
以下是如何使用反射调用方法,以便您可以从 运行 时类型移回编译时类型。
void Main()
{
Type propertyType = typeof(WorkOrder).GetProperty("Status").PropertyType;
Type interfaceType = typeof(ICustomEnum<>).MakeGenericType(propertyType);
bool implements = propertyType.IsAssignableTo(interfaceType);
if (implements)
{
object propertyInstance = Activator.CreateInstance(propertyType);
var method =
this
.GetType()
.GetMethod("SomeMethod", BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(propertyType);
method.Invoke(this, new[] { propertyInstance });
}
}
private void SomeMethod<T>(ICustomEnum<T> customEnum)
{
Console.WriteLine($"Success with {typeof(T)}");
}
输出如下:
Success with WorkOrderStatus
这是运行以上内容所需的杂项代码:
public class WorkOrderStatus : ICustomEnum<WorkOrderStatus> { }
public interface ICustomEnum<T> { }
public class WorkOrder
{
public WorkOrderStatus Status { get; set; }
}