У меня есть этот код
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;