推断接口的泛型类型

本文关键字:泛型类型 接口 | 更新日期: 2023-09-27 17:57:06

-- 上下文

我有以下5个对象

IChangeStatus<T>
myFirstClass : IChangeStatus<firstClassEnum>
mySecondClass : IChangeStatus<secondClassEnum>
myClassHandler<TEntity>
myFirstClassHandler : myClassHandler<myFirstClass>

出于问题的目的,我们可以假设接口仅具有以下属性

T Status { get; }

--问题

1.- 我如何在myClassHandler的方法中询问 TEntity 的实例是否实现了IChangeStatus

2.- 如何迭代一个 IEnumerable 的TEntity假定其特定的 IChangeStatus?

推断接口的泛型类型

要检查您的类是否实现了 IChangeStatus,您可以简单地执行以下操作:

public void FooMethod(ClassType myClass)
{
  var doesImplementIChange = myClass as IChangeStatus<SomeClass>
  if (doesImplementIChange != null)
  {
    // Do stuff..
  }
}

要遍历 IEnumerable 的类,请执行以下操作:

foreach (var data in myClass.OfType<MyType>())
        {
            // Do stuff..
        }

或者,您可以执行以下操作:

foreach (var cls in myClass)
        {
            var myCls = myClass as IChangeStatus<SomeClass>;
            if (myCls != null)
            {
                // Do stuff..
            }
        }

如果要在MyClassHandler中使用IChangeStatus<T>中的T,则必须添加另一个类型参数。例如:

class MyClassHandler<TEntity, TStatus>
    where TEntity : IChangeStatus<TStatus>
{
     public IEnumerable<TStatus> Statuses
     {
          get { return _entities.Select(entity => entity.Status); }
     }
}

where子句将确保实体和状态类型相关。

如果不想这样做,可以添加一个额外的非泛型接口,该接口公开类型为 ObjectStatus 属性。这样你会丢失一些静态类型,但你不需要额外的类型参数。

我发现了另一个SO问题 - 检查类型是否实现了泛型接口,而不考虑泛型类型参数,这给了我一个更通用的答案,这就是我正在寻找的:

return entity.GetType().GetInterfaces()
       .Where(i => i.IsGenericType)
       .Any(i => i.GetGenericTypeDefinition() == typeof(IChangeStatus<>));

至于假设 IChangeStatus 的特定类型的 IEnumerable 迭代,既然我们指向了这一点,那么该类型确实实现了接口,因此具有 Status 属性......所以我选择了动态类型。