推断接口的泛型类型
本文关键字:泛型类型 接口 | 更新日期: 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
子句将确保实体和状态类型相关。
如果不想这样做,可以添加一个额外的非泛型接口,该接口公开类型为 Object
的 Status
属性。这样你会丢失一些静态类型,但你不需要额外的类型参数。
我发现了另一个SO问题 - 检查类型是否实现了泛型接口,而不考虑泛型类型参数,这给了我一个更通用的答案,这就是我正在寻找的:
return entity.GetType().GetInterfaces()
.Where(i => i.IsGenericType)
.Any(i => i.GetGenericTypeDefinition() == typeof(IChangeStatus<>));
至于假设 IChangeStatus 的特定类型的 IEnumerable 迭代,既然我们指向了这一点,那么该类型确实实现了接口,因此具有 Status 属性......所以我选择了动态类型。