C# 确定一个类型是否实现了泛型接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1121834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 08:42:46  来源:igfitidea点击:

Finding out if a type implements a generic interface

c#.netreflection

提问by Alex319

Let's say I have a type, MyType. I want to do the following:

假设我有一个类型,MyType。我想做以下事情:

  1. Find out if MyType implements the IList interface, for some T.
  2. If the answer to (1) is yes, find out what T is.
  1. 找出 MyType 是否为某些 T 实现了 IList 接口。
  2. 如果(1)的答案是肯定的,找出 T 是什么。

It seems like the way to do this is GetInterface(), but that only lets you search by a specific name. Is there a way to search for "all interfaces that are of the form IList" (If possible it woudl also be useful if it worked if the interface was a subinterface of IList.)

这样做的方法似乎是 GetInterface(),但这只能让您按特定名称进行搜索。有没有办法搜索“所有 IList 形式的接口”(如果可能的话,如果接口是 IList 的子接口,它也很有用。)

Related: How to determine if a type implements a specific generic interface type

相关:如何确定一个类型是否实现了特定的泛型接口类型

采纳答案by Anton Tykhyy

// this conditional is necessary if myType can be an interface,
// because an interface doesn't implement itself: for example,
// typeof (IList<int>).GetInterfaces () does not contain IList<int>!
if (myType.IsInterface && myType.IsGenericType && 
    myType.GetGenericTypeDefinition () == typeof (IList<>))
    return myType.GetGenericArguments ()[0] ;

foreach (var i in myType.GetInterfaces ())
    if (i.IsGenericType && i.GetGenericTypeDefinition () == typeof (IList<>))
        return i.GetGenericArguments ()[0] ;

Edit:Even if myTypeimplements IDerivedFromList<>but not directly IList<>, IList<>will show up in the array returned by GetInterfaces().

编辑:即使myType实现IDerivedFromList<>但不是直接实现IList<>IList<>也会显示在由 返回的数组中GetInterfaces()

Update:added a check for the edge case where myTypeis the generic interface in question.

更新:添加了对边缘情况的检查,其中myType有问题的通用接口。

回答by Stan R.

If i understand your question correctly, this is what you are trying to do. If not, please explain further.

如果我正确理解你的问题,这就是你想要做的。如果不是,请进一步解释。

public class MyType : ISomeInterface
{
}

MyType o = new MyType();

if(o is ISomeInterface)
 {
 }

edit:if you change your question, please add the fact that you edited..because now my answer looks like it doesn't belong.

编辑:如果你改变你的问题,请添加你编辑过的事实..因为现在我的答案看起来不属于它。

In that case, here is a very large LINQ

在这种情况下,这是一个非常大的 LINQ

            var item = typeof(MyType).GetInterfaces()
                            .Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList<>))
                            .Select(t => t.GetGenericArguments().First())
                            .FirstOrDefault();

if( item != null )
 //it has a type

回答by Chris Ballance

Type[] typeArray2 = c.GetInterfaces();
for (int num2 = 0; num2 < typeArray2.Length; num2++)
{
     if (this == typeArray2[num2])
     {
          return true;
     }
}

--http://www.hanselman.com/blog/DoesATypeImplementAnInterface.aspx

-- http://www.hanselman.com/blog/DoesATypeImplementAnInterface.aspx

回答by casperOne

Using reflection (and some LINQ) you can easily do this:

使用反射(和一些 LINQ)你可以很容易地做到这一点:

public static IEnumerable<Type> GetIListTypeParameters(Type type)
{
    // Query.
    return
        from interfaceType in type.GetInterfaces()
        where interfaceType.IsGenericType
        let baseInterface = interfaceType.GetGenericTypeDefinition()
        where baseInterface == typeof(IList<>)
        select interfaceType.GetGenericArguments().First();
}

First, you are getting the interfaces on the type and filtering out only for those that are a generic type.

首先,您正在获取类型上的接口,并仅过滤掉泛型类型的接口。

Then, you get the generic type definition for those interface types, and see if it is the same as IList<>.

然后,您获得这些接口类型的泛型类型定义,并查看它是否与IList<>.

From there, it's a simple matter of getting the generic arguments for the original interface.

从那里,获取原始接口的通用参数很简单。

Remember, a type can have multiple IList<T>implementations, which is why the IEnumerable<Type>is returned.

请记住,一个类型可以有多个IList<T>实现,这IEnumerable<Type>就是返回 的原因。

回答by GenericProgrammer

As a helper method extension

作为辅助方法扩展

public static bool Implements<I>(this Type type, I @interface) where I : class  
{
    if(((@interface as Type)==null) || !(@interface as Type).IsInterface)
        throw new ArgumentException("Only interfaces can be 'implemented'.");

    return (@interface as Type).IsAssignableFrom(type);
}

example usage:

用法示例:

var testObject = new Dictionary<int, object>();
result = testObject.GetType().Implements(typeof(IDictionary<int, object>)); // true!

回答by user989279

    public static bool Implements<I>(this Type type) where I : class
    {
         if (!typeof(I).IsInterface)
         {
             throw new ArgumentException("Only interfaces can be 'implemented'.");
         }

         return typeof(I).IsAssignableFrom(type);
    }

回答by Knasterbax

Using Anton Tykhyy's proposal, here is a small Extension Method to check if some type implements a generic interface with one given generic type parameters:

使用 Anton Tykhyy 的提议,这里有一个小的扩展方法来检查某个类型是否使用给定的泛型类型参数实现了泛型接口:

public static class ExtensionMethods
{
    /// <summary>
    /// Checks if a type has a generic interface. 
    /// For example 
    ///     mytype.HasGenericInterface(typeof(IList<>), typeof(int)) 
    /// will return TRUE if mytype implements IList<int>
    /// </summary>
    public static bool HasGenericInterface(this Type type, Type interf, Type typeparameter)
    {
        foreach (Type i in type.GetInterfaces())
            if (i.IsGenericType && i.GetGenericTypeDefinition() == interf)
                if (i.GetGenericArguments()[0] == typeparameter)
                    return true;

        return false;
    }
}