Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查泛型类型是否从泛型接口继承_C#_.net_Generics_Inheritance_Interface - Fatal编程技术网

C# 检查泛型类型是否从泛型接口继承

C# 检查泛型类型是否从泛型接口继承,c#,.net,generics,inheritance,interface,C#,.net,Generics,Inheritance,Interface,我有一个基本接口,我响应 public interface IResponse { int CurrentPage { get; set; } int PageCount { get; set; } } …从基本接口继承的通用接口ICollectionResponse public interface ICollectionResponse<T> : IResponse { List<T> Collection { get; set; } }

我有一个基本接口,我响应

public interface IResponse
{
    int CurrentPage { get; set; }
    int PageCount { get; set; }
}
…从基本接口继承的通用接口ICollectionResponse

public interface ICollectionResponse<T> : IResponse
{
    List<T> Collection { get; set; }
}
public class EmployeesResponse : ICollectionResponse<Employee>
{
    public int CurrentPage { get; set; }
    public int PageCount { get; set; }
    public List<Employee> Collection { get; set; }
}

public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
公共接口ICollectionResponse:IResponse
{
列表集合{get;set;}
}
…和一个类EmployeesResponse,它继承自泛型接口,随后继承自基接口

public interface ICollectionResponse<T> : IResponse
{
    List<T> Collection { get; set; }
}
public class EmployeesResponse : ICollectionResponse<Employee>
{
    public int CurrentPage { get; set; }
    public int PageCount { get; set; }
    public List<Employee> Collection { get; set; }
}

public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
公共类员工响应:ICollectionResponse
{
public int CurrentPage{get;set;}
public int PageCount{get;set;}
公共列表集合{get;set;}
}
公营雇员
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
我的问题在这里。我有一个通用的任务方法,它返回基本接口的一个实例IResponse。在这个方法中,我需要确定T是否从ICollectionResponse实现

public class Api
{
    public async Task<IResponse> GetAsync<T>(string param)
    {
        // **If T implements ICollectionResponse<>, do something**

        return default(IResponse);
    }
}
公共类Api
{
公共异步任务GetAsync(字符串参数)
{
//**如果T实现ICollectionResponse,请执行某些操作**
返回默认值(i响应);
}
}
我尝试了IsAssignableFrom()方法的所有版本,但均未成功,包括:

typeof(ICollectionResponse<>).IsAssignableFrom(typeof(T))
typeof(ICollectionResponse)。IsAssignableFrom(typeof(T))

非常感谢您的反馈。

这对您有用吗

List<bool> list = new List<bool>();

foreach (var i in list.GetType().GetInterfaces())
{
  if (i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>))
  { }
}
List List=新列表();
foreach(list.GetType().GetInterfaces()中的变量i)
{
if(i.IsGenericType&&i.GetGenericTypeDefinition()==typeof(IList))
{ }
}

由于您没有任何
t的实例,因此必须使用反射

if (typeof(T).GetInterfaces().Any(
  i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICollectionResponse<>)))
{
  Console.WriteLine($"Do something for {param}");
}
if(typeof(T).GetInterfaces().Any(
i=>i.IsGenericType&&i.GetGenericTypeDefinition()==typeof(ICollectionResponse)))
{
WriteLine($“为{param}做点什么”);
}
IsGenericType
用于查找任何通用接口-在本例中,它过滤掉
iResponse
,该接口也由
GetInterfaces()
返回

然后
GetGenericTypeDefinition
ICollectionResponse
移动到我们要检查的类型
ICollectionResponse
。因为我们不知道员工是什么


正如评论中指出的,可以实现多个接口,例如
ICollectionResponse、ICollectionResponse
。上面的代码将运行“dosomething”语句,不关心是否有一个匹配项或多个匹配项。如果一个类型为不同的
t
多次实现
ICollectionResponse
会发生什么?我能想到的最简单的事情是
typeof(t).GetInterfaces().Where(I=>I.IsGenericType&&I.GetGenericTypeDefinition()==typeof(ICollectionResponse))
。这很难看,并且可能返回多个实例,这表明您可能需要重新考虑这种方法。例如,您可以只搜索适当类型的公共
集合
属性——这也需要反射,但没有“类型安全”的薄薄外衣(在本例中,您无论如何都没有该属性——您无法静态强制转换到
ICollectionResponse
,因为您不知道类型参数)。好问题。接口的任何后续实现都必须显式完成。这不应该发生,如果发生了,这将是一个特例。但是,可能应该考虑到它,并处理每个版本的
集合
。应该可以使用泛型抽象类来代替泛型接口为了防止多重继承,通常最好在编译期间使用.typeof。因为您将使用runtime定义类型T,所以您可能应该使用GetType()-因为它在runtime中工作得更好。