简体   繁体   中英

Infer Generic Type of Interface

-- Context

I have the following 5 objects

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 ?

2.- How can I iterate over an IEnumerable of TEntity assuming their specific IChangeStatus?

To check if your class implements IChangeStatus, you can simply do:

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

To iterate over an IEnumerable of your classes:

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. 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.

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 . You'd lose some static typing that way, but you would not need the extra type parameter.

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:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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