简体   繁体   English

推断接口的通用类型

[英]Infer Generic Type of Interface

-- Context -上下文

I have the following 5 objects 我有以下5个对象

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

myClassHandler<TEntity>
myFirstClassHandler : myClassHandler<myFirstClass>

for the purposes of the question we can assume the interface only has the property 出于问题的目的,我们可以假定接口仅具有属性

T Status { get; }

-- Questions -问题

1.- How can I ask in a method in myClassHandler if an instance of TEntity implements IChangeStatus ? 1.-如何在myClassHandler的方法中myClassHandler TEntity的实例是否实现IChangeStatus

2.- How can I iterate over an IEnumerable of TEntity assuming their specific IChangeStatus? 2.-如何假设其特定的IChangeStatus遍历TEntity的IEnumerable?

To check if your class implements IChangeStatus, you can simply do: 要检查您的类是否实现IChangeStatus,可以简单地执行以下操作:

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

To iterate over an IEnumerable of your classes: 要遍历您的IEnumerable类:

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

or, you could do: 或者,您可以执行以下操作:

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

If you want to use T from IChangeStatus<T> in MyClassHandler , you will have to add another type parameter. 如果你想使用TIChangeStatus<T>MyClassHandler ,你必须添加另一种类型的参数。 For example: 例如:

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

The where clause will ensure that the entity and status types are correlated. where子句将确保实体和状态类型相关联。

If you don't want to do that, you could add an additional non-generic interface that exposes a Status property of the type Object . 如果您不想这样做,则可以添加一个额外的非通用接口,该接口公开Object类型的Status属性。 You'd lose some static typing that way, but you would not need the extra type parameter. 这样会丢失一些静态类型,但是不需要额外的type参数。

I found this other SO Question - Check if a type implements a generic interface without considering the generic type arguments which gave me a more generic answer which is what I was looking for: 我发现了另一个SO问题-检查类型是否实现了通用接口,而没有考虑通用类型参数 ,这为我提供了一个更通用的答案,这就是我想要的:

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

As to the iteration over the IEnumerable assuming the specific type of IChangeStatus, since we got that to point then the type does implement the interface thus has a Status property... so I went for dynamic type. 至于假定IChangeStatus的特定类型的IEnumerable的迭代,由于我们已经指出了这一点,那么该类型确实实现了接口,因此具有Status属性...所以我选择了动态类型。

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

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