简体   繁体   English

检查类的泛型参数是否实现接口

[英]Check if generic parameter of a class implements an interface

I have a following generic class: 我有一个以下泛型类:

public class SearchResult<T>
{
    public int ResultCount { get; set; }
    public IEnumerable<T> Result { get; set; }
}

I also have a Bird class, which implements IFlyble interface: 我还有一个Bird类,它实现了IFlyble接口:

public class Bird : IFlyable
{
    public void Fly() {}
}

public interface IFlyable
{
    void Fly();
}

I also have a variable res of type object . 我还有一个类型为object的变量res How do I check if res is a SearchResult<IFlyable> ? 如何检查res是否是SearchResult<IFlyable>

I tryied this way: 我这样试试:

if (res.GetType().IsAssignableFrom(typeof(SearchResult<IFlyable>)))
{
    ///
}

And this way: 这样:

if(res is SearchResult<IFlyable>)
{
    ///
}

But it does not seems to work. 但它似乎不起作用。

The problem you are having is probably due to the fact that SearchResult<Bird> is not convertible to SearchResult<IFlyable> because SearchResult<T> is invariant in T . 您遇到的问题可能是由于SearchResult<Bird> 无法转换SearchResult<IFlyable>因为SearchResult<T>T是不变的。

C# only admitís generic type variance in interfaces and delegates. C#只允许接口和委托中的泛型类型差异。 You need to define an ISearchResult<> interface that is covariant in its generic type. 您需要定义一个ISearchResult<>接口,该接口在其泛型类型中是协变的。

In your case, if it's accepatable that T Is only used as an output you could define such interface as follows: 在您的情况下,如果可以接受T仅用作输出,则可以按如下方式定义此类接口:

public interface ISearchResult<out T>
{
     int ResultCount { get; }
     IEnumerable<T> Result { get; }
}

And now a ISearchResult<Bird> is a ISearchResult<IFlyable> because you've given the compiler enough information so that it can verify that the conversion is in fact safe 现在, ISearchResult<Bird>是一个ISearchResult<IFlyable>因为您已经为编译器提供了足够的信息,以便它可以验证转换实际上是否安全

You can also try this using reflection, which also works and no need to create another interface. 您也可以使用反射来尝试这个,它也可以工作,不需要创建另一个接口。

static void Main()
{
    var sr = new SearchResult<Bird>();
    Console.WriteLine(IsSearchResultIFlyable(sr.GetType())
        ? "sr is SearchResult<IFlyable>"
        : "sr is Not SearchResult<IFlyable>");

    Console.ReadLine();
}

public static bool IsSearchResultIFlyable(Type t)
{
    if (!t.IsGenericType) return false;
    if (t.GetGenericTypeDefinition() != typeof(SearchResult<>)) return false;

    var gr = t.GetGenericArguments();
    return gr.Length == 1 && typeof(IFlyable).IsAssignableFrom(gr[0]);
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM