PedroC88
PedroC88

Reputation: 3829

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?

Upvotes: 0

Views: 185

Answers (3)

PedroC88
PedroC88

Reputation: 3829

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.

Upvotes: 0

Eli Arbel
Eli Arbel

Reputation: 22739

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.

Upvotes: 2

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

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

Upvotes: 2

Related Questions