简体   繁体   English

查明 class 是否通过反射实现接口

[英]Find out if class implements an interface thru reflection

I have the following class in c#:我在 c# 中有以下 class:

public class WorkOrderStatus : ICustomEnum<WorkOrderStatus>
{
}

during runtime I need to figure out if a property of the following class implements the custom interface.在运行时,我需要确定以下 class 的属性是否实现了自定义接口。

public class WorkOrder{
    public WorkOrderStatus Status {get;set;}
}

So I tried to do the following(using reflection to figure it out):所以我尝试执行以下操作(使用反射来弄清楚):

prop.PropertyType.GetInterfaces().Contains(typeof(ICustomEnum));

But this says that ICustomEnum requires a generic type.但这表示 ICustomEnum 需要泛型类型。 So i Tried to do the following, but it doesnt work:所以我尝试执行以下操作,但它不起作用:

var type = prop.GetType(); 
prop.PropertyType.GetInterfaces().Contains(typeof(ICustomEnum<typeof(type)>));

saying type is a variable but used like a type说类型是一个变量,但像类型一样使用

[Edit 1] [编辑 1]

I later need to be able to create an instance of WorkOrderStatus or any other class that implements this interface thru reflection like this:我稍后需要能够创建 WorkOrderStatus 的实例或通过反射实现此接口的任何其他WorkOrderStatus ,如下所示:

var instance = (ICustomEnum<WorkOrderStatus|SomeOtherStatus...>)Activator.CreateInstance(prop.PropertyType);

It's quite simple to do with IsAssignableTo :使用IsAssignableTo非常简单:

Type propertyType = typeof(WorkOrder).GetProperty("Status").PropertyType;
Type interfaceType = typeof(ICustomEnum<>).MakeGenericType(propertyType);
bool implements = propertyType.IsAssignableTo(interfaceType);

And, you might find that typeof(ICustomEnum<>).MakeGenericType(propertyType);而且,您可能会发现typeof(ICustomEnum<>).MakeGenericType(propertyType); solves your problem in your code directly.直接在您的代码中解决您的问题。

So instead of typeof(ICustomEnum<typeof(type)>) you write typeof(ICustomEnum<>).MakeGenericType(type) .所以代替typeof(ICustomEnum<typeof(type)>)你写typeof(ICustomEnum<>).MakeGenericType(type)


Here's how you would use reflection to call a method so that you can move from run-time types back to compile-time types.以下是使用反射调用方法的方法,以便您可以从运行时类型移回编译时类型。

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)}");
}

That outputs the following:输出以下内容:

Success with WorkOrderStatus

Here's the sundry code you need to run the above:这是运行上述代码所需的各种代码:

public class WorkOrderStatus : ICustomEnum<WorkOrderStatus> { }
public interface ICustomEnum<T> { }
public class WorkOrder
{
    public WorkOrderStatus Status { get; set; }
}

You could use GetGenericTypeDefinition for this purpose.为此,您可以使用GetGenericTypeDefinition For example,例如,

propertyInfo.PropertyType
           .GetInterfaces()
           .Where(x => x.IsGenericType)
           .Any(i => i.GetGenericTypeDefinition() == typeof(ICustomEnum<>));

To retrieve all properties of the Type which implements the particular generic interface, you could要检索实现特定通用接口的 Type 的所有属性,您可以

var properties = typeof(WorkOrder).GetProperties();
var result = properties.Where(property=>property.PropertyType
                                               .GetInterfaces()
                                               .Where(x => x.IsGenericType)
                                               .Any(i => i.GetGenericTypeDefinition() == typeof(ICustomEnum<>)));

you can try this你可以试试这个

bool implements = typeof(WorkOrder).GetProperties()
.Any(p => p.PropertyType.GetInterfaces().Any(pt => pt.Name  ==typeof(ICustomEnum<>).Name));

or generic variant或通用变体

printProperties<WorkOrder,ICustomEnum<WorkOrder>>();

public static void printProperties<T1,T2>()
{
    foreach (var property in typeof(T1).GetProperties())
    {   
    var contains= property.PropertyType.GetInterfaces().Any(pt => pt.Name  ==typeof(T2).Name);
    
     if(contains)Console.WriteLine("Property "+ property.Name + " contains interface "+typeof(T2).Name);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用反射创建实现T类型接口的类 - Using reflection to create a class that implements an interface of type T 查找使用Ninject实现通用接口的类 - Find class that implements generic interface with Ninject 如果我的班级实现了接口,ReSharper不能确定并链接2吗? - If my class implements an interface, can't ReSharper figure that out and link the 2? 如何使用反射来查找开放泛型类型上的哪个开放泛型参数实现泛型接口? - How can I use reflection to find which open generic argument on an open generic type implements a generic interface? 如何在实现特定接口的外部引用中查找类? - How to Find a class in external reference that implements certain interface? C#反射可返回其Type实现特定接口的类中的所有属性 - C# reflection to return all properties in a class whose Type implements a specific interface 如何确定对象的类型是否实现了IEnumerable <X> 其中X使用Reflection从Base派生 - How to find out if an object's type implements IEnumerable<X> where X derives from Base using Reflection 如何找出类型是否实现泛型基类 - How to find out if a type implements generics base class 如何找出.net类实现哪些接口? - How to find out which interfaces a .net class implements? 如何使用C#中的反射查找实现泛型抽象类的所有类? - How to find all classes that implements a generic abstract class using reflection in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM