Есть ли способ справиться с неизвестными универсальными типами?

У меня есть этот код

public interface IConsumable<T> {
  void Consume(T item);
}

public interface IProducer<T> {
  IConsumable<T> Consumer { get; set; }
  void Produce();
}

public class MyClass : MyType, 
  IConsumable<ISpecifcItem>
{
  public void Consume(ISpecificItem item) { ... }
}

public class MySpecificItemProducer
  : IProducer<ISpecificItem> {
  public IConsumable<ISpecificItem> Consumer { get; set; }
  public void Produce() {
    ISpecificItem myItem = new MyVerySpecificItem();
    Consumer.Consume(myItem);
  }
}

Затем у меня есть контроллер, который принимает любой MyType , обнаруживает все типы IConsumable <> , которые он реализует, и получает тип параметра универсального типа. С помощью этого списка типов обнаруживаются все производители, реализующие IProducer . Это несложно:

var consumerTypes =
    myType.GetType().GetInterfaces()
    .Where(x => x.IsGenericType)
    .Where(x => x.GetGenericTypeDefinition() ==
        typeof(IConsumable<>));

  if (consumerTypes.Any()) {
    var instanceTypes = consumerTypes
      .Select(x => x.GetGenericArguments().First())
      .Select(x => typeof(IProducer<>).MakeGenericType(x));
    // for each of those types discover classes where 
    // it assignable from
    // and instantiate the class using the Activator
  }

Но проблема в том, как установить свойство Consumer производителя? Экземпляр производителя для меня является объектом, я не могу преобразовать его в IProducer , потому что я не могу использовать T как переменную.

Я могу сделать это с помощью отражения продюсераInstance.GetType (). GetProperty ("Consumer"). SetValue (продюсерInstance, consumerInstance, null); но я хотел знать, есть ли другой способ?

Интересно, что это не удалось во время выполнения:

MyClass consumerInstance;
dynamic test = producerInstance;
test.Consumer = consumerInstance;

Он жаловался, что тип consumerInstance несовместим с типом свойства.

РЕДАКТИРОВАТЬ: динамический пример работал только тогда, когда consumerInstance также был динамическим, например:

dynamic testC = consumerInstance;
dynamic testP = producerInstance;
testP.Consumer = testC;
0
задан Andreas 11 March 2012 в 21:01
поделиться