简体   繁体   中英

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:

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

public interface IFlyable
{
    void Fly();
}

I also have a variable res of type object . How do I check if res is a 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 .

C# only admitís generic type variance in interfaces and delegates. You need to define an ISearchResult<> interface that is covariant in its generic type.

In your case, if it's accepatable that T Is only used as an output you could define such interface as follows:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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