繁体   English   中英

推断接口的通用类型

[英]Infer Generic Type of Interface

-上下文

我有以下5个对象

IChangeStatus<T>
myFirstClass : IChangeStatus<firstClassEnum>
mySecondClass : IChangeStatus<secondClassEnum>

myClassHandler<TEntity>
myFirstClassHandler : myClassHandler<myFirstClass>

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

T Status { get; }

-问题

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

2.-如何假设其特定的IChangeStatus遍历TEntity的IEnumerable?

要检查您的类是否实现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..
            }
        }

如果你想使用TIChangeStatus<T>MyClassHandler ,你必须添加另一种类型的参数。 例如:

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

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

如果您不想这样做,则可以添加一个额外的非通用接口,该接口公开Object类型的Status属性。 这样会丢失一些静态类型,但是不需要额外的type参数。

我发现了另一个SO问题-检查类型是否实现了通用接口,而没有考虑通用类型参数 ,这为我提供了一个更通用的答案,这就是我想要的:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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