Вывод универсального типа с производным типом

класс Property это abstract

У меня есть следующий метод:

private IPortionOfPropertyInfoAddEditView<T> getPropertyEditPortion<T>(T property) where T : Property { /*details unimportant*/ }

Property P = PropertyFactoryMethod.GetSomePropertyInstance();

var PropertyInfoPortion = getPropertyEditPortion(P);

Когда я вызываю метод таким образом, выводится тип Property, а не более производный Well или RealEstate, предположительно потому, что вывод типа выполняется во время компиляции. Я работал над этим, приведя P к dynamic, например:

var PropertyInfoPortion = getPropertyEditPortion((dynamic)P);

который отлично работает. Мне просто интересно, есть ли более элегантный способ сделать это.

ИЗМЕНИТЬ

Извините, я всегда стараюсь показывать наименьшее количество кода, чтобы донести суть, чтобы не было слишком беспорядка. Вот полный метод:

    private IPortionOfPropertyInfoAddEditView<T> getPropertyEditPortion<T>(T property) where T : Property {
        return StructureMap.ObjectFactory.GetInstance<IPortionOfPropertyInfoAddEditView<T>>();         
    }

У меня есть экземпляр Property (который является абстрактным), и я использовал вывод типа, чтобы получить истинный тип для передачи моему IoC, не прибегая к отражению (чтобы собрать правильный общий тип). Мне просто интересно, есть ли трюк, с помощью которого это можно сделать без приведения dynamic, но я думаю, что нет. Спасибо всем.

ИЗМЕНИТЬ 2

Я пытаюсь создать IPortionOfPropertyInfoAddEditView<T>

Экземпляр My Property, P, относится к типу, который нужен IPortionOfPropertyInfoAddEditView, но он типизирован как Property, а не как производный тип. Я был бы просто счастлив, если бы мог сказать:

StructureMap.ObjectFactory.GetInstance<IPortionOfPropertyInfoAddEditView<typeof(P)>>()

Но это явно не разрешено. Я подумал, что вывод типа с динамическим приведением будет следующей лучшей вещью, мне просто было интересно, есть ли у кого-нибудь лучший способ. Извините, что не ясно с самого начала!


person Adam Rackis    schedule 18.03.2011    source источник
comment
Что в теле метода делает настолько важным, чтобы аргумент-тип был таким же, как (предположительно) тип аргумента во время выполнения?   -  person Ani    schedule 18.03.2011
comment
Интересно... Сегодня я кое-что узнал! Я думаю, Адам, то, что ты сделал, довольно элегантно... Как и @Ani, мне тоже интересно, какая разница...   -  person Eugenio De Hoyos    schedule 18.03.2011
comment
@ani — результат метода основан на аргументе типа — он должен быть наиболее производным типом   -  person Adam Rackis    schedule 18.03.2011
comment
@Adam: Если бы вы могли привести простой пример того, чем отличается результат, это могло бы нам помочь.   -  person Eugenio De Hoyos    schedule 18.03.2011
comment
@Adam: Но вы не показали нам «желаемое» (нединамическое) использование метода. Без контекста действительно трудно ответить на этот вопрос разумно. Еще один вопрос: является ли интерфейс ковариантным?   -  person Ani    schedule 18.03.2011
comment
По сути, этот метод просто вызывает мой IoC для получения экземпляра IPortionOfProprtyEdit‹T›. У меня есть экземпляр моего свойства (T выше), и я не хотел использовать отражение для создания универсального типа для передачи в IoC, поэтому я использовал вывод типа метода.   -  person Adam Rackis    schedule 18.03.2011
comment
Ани - я просил выяснить, существует ли желаемое нединамическое решение - я думаю, что нет :) Интерфейс не является ковариантным - если бы это было так, был бы другой вариант?   -  person Adam Rackis    schedule 18.03.2011
comment
Показан полный метод - извините за то, что изначально не разместил достаточно информации   -  person Adam Rackis    schedule 18.03.2011
comment
@Adam: я имел в виду показать нам желаемое использование. Например, какой переменной вы (в идеале) хотели бы присвоить результат метода, если логический вывод работает с типом времени выполнения? object? dynamic? Ковариантное преобразование в IPortionOfPropertyInfoAddEditView<LessSpecificType>? Нестандартный IPortionOfPropertyInfoAddEditView? В вашем комментарии действительно сложно найти смысл, результат метода основан на аргументе типа - он должен быть наиболее производным типом.   -  person Ani    schedule 18.03.2011
comment
@Adam: я только что видел твою правку. Вы нигде не используете аргумент! Не могли бы вы объяснить, почему вы передаете аргумент в первую очередь? Это манекен, чтобы помочь компилятору вывести типы?   -  person Ani    schedule 18.03.2011
comment
Я использую общий параметр в конце единственной строки метода (возможно, вам придется прокрутить вправо — если вы используете iPhone, вам не повезло :)). Тип, который я создаю, IPortionOfProperty‹T› сам по себе является универсальным. У меня есть экземпляр, представляющий тип, который примет IPortionOfProperty. Поскольку вы не можете сказать (эквивалентно) new GenericType‹typeof(P)›, вместо этого я использовал вывод типа.   -  person Adam Rackis    schedule 18.03.2011
comment
Скажите последнее редактирование - я должен был включить больше информации в исходный вопрос   -  person Adam Rackis    schedule 18.03.2011


Ответы (2)


Невозможно сделать это с помощью дженериков, поскольку дженерики всегда работают со значениями статического типа. Тот факт, что вы обошли это с помощью механизма времени выполнения (dynamic), является хорошей подсказкой.

Существует ряд хороших решений во время выполнения, но это зависит от того, что именно вы хотите делать с property (т. е. к каким членам вы хотите получить доступ, видимость указанных членов и т. д.).

person Jon    schedule 18.03.2011
comment
использование механизма времени выполнения (динамического) - хороший совет для этого - да, я знаю. Я просто хотел убедиться. Спасибо и +1 - person Adam Rackis; 18.03.2011

Первое, что приходит в голову, это сделать реализацию getPropertyEditPortion методом класса Property.

Тогда вам не нужно заботиться о производном типе P в этом случае, вы просто вызываете свой метод, и запускается правильная реализация.

Если это невозможно, то использование ключевого слова dynamic кажется уместным.

person wsanville    schedule 18.03.2011
comment
Это невозможно - это приведет к плохим зависимостям, но хорошая мысль. +1 - person Adam Rackis; 18.03.2011