C# 推断接口的泛型类型

C# 推断接口的泛型类型,c#,.net,generics,interface,C#,.net,Generics,Interface,-上下文 我有以下5个对象 IChangeStatus<T> myFirstClass : IChangeStatus<firstClassEnum> mySecondClass : IChangeStatus<secondClassEnum> myClassHandler<TEntity> myFirstClassHandler : myClassHandler<myFirstClass> -问题 1.-如果TEntity的实例实

-上下文

我有以下5个对象

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

myClassHandler<TEntity>
myFirstClassHandler : myClassHandler<myFirstClass>
-问题

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


2.-如何在假定IEnumerable的特定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..
            }
        }

要检查类是否实现了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,则必须添加另一个类型参数。例如:

class MyClassHandler<TEntity, TStatus>
    where TEntity : IChangeStatus<TStatus>
{
     public IEnumerable<TStatus> Statuses
     {
          get { return _entities.Select(entity => entity.Status); }
     }
}
where子句将确保实体和状态类型相互关联

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

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

class MyClassHandler<TEntity, TStatus>
    where TEntity : IChangeStatus<TStatus>
{
     public IEnumerable<TStatus> Statuses
     {
          get { return _entities.Select(entity => entity.Status); }
     }
}
where子句将确保实体和状态类型相互关联

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

我找到了另一个,它给了我一个更一般的答案,这正是我想要的:

return entity.GetType().GetInterfaces()
       .Where(i => i.IsGenericType)
       .Any(i => i.GetGenericTypeDefinition() == typeof(IChangeStatus<>));
至于IEnumerable上的迭代,假设特定类型的IChangeStatus,既然我们得到了这一点,那么该类型确实实现了接口,因此具有状态属性。。。所以我选择了打字。

我找到了另一个,它给了我一个更一般的答案,这正是我想要的:

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

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

关于问题1-您是在寻找一种方法来检查运行时it TEntity实现IChangeStatus,还是一种方法来确保在编译时TEntity始终是IChangeStatus类型?我刚才看到了这条评论,我在寻找运行时检查,我已经在另一个so问题中找到了它,是在我的回答中。关于问题1,您是在寻找一种方法来检查运行时it TEntity实现IChangeStatus,还是一种方法来确保在编译时TEntity始终是IChangeStatus类型?我刚才看到了这条评论,我是在寻找运行时检查,我已经在另一个问题中找到了它,在我的回答中是这样的。这是我实现它的方式,但是如果列表是我不喜欢的。。。我想可能有更好的解决方案。至于检查id是否实现了接口,除了强制转换和空检查之外没有其他选择。但是对于foreach语句,您可以使用第一个选项,其中没有if语句。这是我实现它的方式,但我不喜欢ifs列表。。。我想可能有更好的解决方案。至于检查id是否实现了接口,除了强制转换和空检查之外没有其他选择。但是对于foreach语句,您可以使用第一个选项,其中没有if语句