在C#中,如果我的对象支持该接口,我如何检查T是否为IInterface类型并强制转换为?

leo*_*ora 15 c# generics interface

在C#中,我有一个传递的功能T使用generics,我想运行一个检查,看看是否Tobject一个实现了interface,如果这样称呼的一个methodsinterface.

我不希望T只有该类型的约束.是否有可能做到这一点?

例如:

public class MyModel<T> : IModel<T> where T : MyObjectBase
{
    public IQueryable<T> GetRecords()
    {
        var entities = Repository.Query<T>();
        if (typeof(IFilterable).IsAssignableFrom(typeof(T)))
        {
            //Filterme is a method that takes in IEnumerable<IFilterable>
            entities = FilterMe(entities));
        }
        return entities;
    }

    public IEnumerable<TResult> FilterMe<TResult>(IEnumerable<TResult> linked) where TResult : IFilterable
    {
        var dict = GetDict();
        return linked.Where(r => dict.ContainsKey(r.Id));
    }
 }
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

错误21类型'TResult'不能在泛型类型或方法'FilterMe(System.Collections.Generic.IEnumerable)'中用作类型参数'TResult'.没有从'TResult'到'IFilterable'的隐式引用转换.

sir*_*ide 20

缺少的是Cast<>():

if(typeof(IFilterable).IsAssignableFrom(typeof(T))) {
    entities = FilterMe(entities.Cast<IFilterable>()).AsQueryable().Cast<T>();
}
Run Code Online (Sandbox Code Playgroud)

请注意使用Cast<>()将实体列表转换为正确的子类型.除非T实现IFilterable,否则此强制转换将失败,但由于我们已经检查过,我们知道它会.


SLa*_*aks 17

if (typeof(IMyInterface).IsAssignableFrom(typeof(T))
Run Code Online (Sandbox Code Playgroud)

这将检查是否IMyInterface可以从类型实例中分配类型的变量T.