Использование обобщений, когда тип не известен во время компиляции - PullRequest
2 голосов
/ 17 июля 2009

Платформа: C # 2.0 WinForms

У меня есть фабричный класс, который обеспечивает создание экземпляра определенного преобразователя данных в зависимости от типа, который я отправляю, код таков:

public static IDataMapper<T> GetMapper<T>() where T: IDto
{
    Type mapperType = MapperLocator.GetMapper(typeof(T));

    return (IDataMapper<T>)mapperType.Assembly.CreateInstance(mapperType.FullName);
}

Я использую DynamicProxy2 для перехвата вызовов методов для моих объектов DTO. В моем методе перехвата я пытаюсь вызвать вышеупомянутую фабрику, используя тип из Invocation.TargetType. Однако это возвращается с исключением:

Не удалось найти тип или имя пространства имен 'invocation'.

Очевидно, это потому, что любые вызовы универсального метода должны явно знать тип из того, что я понимаю во время компиляции. Очевидно, что я не могу сделать это в этом случае, и я определенно не собираюсь делать оператор switch для всех моих объектов DTO.

Итак, вы, ребята, можете предложить стратегию или указать, что я делаю неправильно? Я пытаюсь сделать это как можно более универсальным, чтобы оно могло подходить для всех моих объектов и любых новых, а также переносимости кода в другие проекты.

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 17 июля 2009

Я недостаточно знаком с DTO, чтобы знать, достаточно ли здесь информации для полного решения. Тем не менее, другой ответ в основном правильный; компилятору C # требуется информация о типе во время компиляции.

Однако есть способ обойти это: отражение. System.Reflection (в частности, MethodInfo в вашем случае, я думаю) позволит вам написать полностью универсальное решение.

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

0 голосов
/ 17 июля 2009

К сожалению, выхода из этого нет; компилятору .NET C # необходимо знать тип во время компиляции для обобщений; вам придется найти другой метод.

Возможно, вы можете использовать бокс / распаковку и не-дженерики, но я не знаю много о том, как бы вы это реализовали. В качестве альтернативы вы можете использовать System.Reflection. Опять же, я не знаю, как это сделать.

...