Отражение - приведение объекта к интерфейсу <interface> - PullRequest
0 голосов
/ 01 июня 2018

Исходя из Как отразить интерфейсный тип во время выполнения У меня есть экземпляр типа, который, я знаю, унаследован от базового типа DataPointProcessorBase Этот базовый класс относительно прост

public abstract class DataPointProcessorBase<T> : IDataPointProcessor<T> where T : class, IDataPointInput, new()
{            
    public abstract DataPointOutputBase GetOutput(T input);
}

Age_Input реализует интерфейс, а Age_Processor настроен на его получение

public class Age_Input : DataPointInputBase, IDataPointInput
{
    public int AgeExact { get; set; }    
}
public class Age_Processor : DataPointProcessorBase<Age_Input> 
{
    ...
}

Используя отражение, я на полпути к его правильному приведению, чтобы я мог вызвать GetOutput ()

Любые идеи, почему я не могу попасть в первую очередь, если утверждение ниже?

var instance = Activator.CreateInstance(type);

if (instance is IDataPointProcessor<IDataPointInput>)//why can I not cast interface here?
{
    //false        
}

if (instance is IDataPointProcessor<Age_Input>)//hard-coded - works fine
{
    var processor = instance as IDataPointProcessor<Age_Input>;
    Age_Input temp = item as Age_Input;
    if (temp is IDataPointInput)
    {
        //also true
    }
    var result = processor.GetOutput(temp);
}

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Этот вопрос задают каждый день.Еще раз!

Можно ли использовать корзину с яблоками, когда вам нужна корзина с фруктами?Нет.

Почему бы и нет?Потому что вы можете положить банан в корзину с фруктами, но вы не можете положить банан в корзину с яблоками.

Поэтому вы не можете использовать корзину с яблоками, где нужна корзина с фруктами.

Аналогично, корзина с фруктами не может использоваться в качестве корзины с яблоками, поскольку она может уже содержать банан..

Отношение "a C<X> может использоваться как C<Y>, если X может использоваться как Y", называется ковариация , и C # поддерживает толькоковариация в очень ограниченном наборе обстоятельств:

  • C<T> должен быть интерфейсом или делегатом
  • Объявление интерфейса или делегата должно быть помечено как безопасное для отклонения.
  • Компилятор должен успешно проверить, что объявление отклонения гарантированно безопасно.
  • Оба X и Y должны быть ссылочными типами.

В вашем случае выу вас есть первое и четвертое свойства, но у вас нет второго и третьего.

Пометить IDataPointProcessor<T> следующим образом:

interface IDataPointProcessor<out T>

, что примерно означает "T" используется только в выходных позициях, никогда не вводите позиции ".Если в корзинах нет возможности добавлять фрукты, то возражение - вы не можете положить банан в корзину с яблоками - исчезает, и оно становится законным.

Если сборка завершится успешно, ковариация начнет работатьIDataPointProcessor.Если нет, вы, вероятно, используете T в положении, когда T может течь в .Правила немного более тонкие, чем я здесь обобщаю;если вам нужно подробное описание, я написал его здесь: https://blogs.msdn.microsoft.com/ericlippert/2009/12/03/exact-rules-for-variance-validity/

Вот почему вы можете использовать IEnumerable<Giraffe> в качестве IEnumerable<Animal> - все четыре условия соблюдены.

0 голосов
/ 01 июня 2018

Я решил это и Как отразить интерфейсный тип во время выполнения , полностью исключив проблему, не используя отражение.Полный ответ на этой странице, если кому-то интересно

Спасибо всем за ваше время

@ Эрик Я действительно нашел вашу статью заранее, но в тот момент у меня заболела голова!

0 голосов
/ 01 июня 2018

Из того, что я понимаю, принцип работы универсальных типов в компиляторе C # заключается в том, что строго типизированные типы, которые используются в этих универсальных параметрах во время компиляции (то есть они используются в вашем коде), генерируются динамически как строго типизированные классы (Возможно на уровне MSIL).

Таким образом, во время выполнения ваш объект не наследовал тип с универсальным типом, а вместо этого унаследовал тип строгого типа.

Вы можете создать регистр переключения для каждого возможного строго типизированного типа и попытаться привести его к типу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...