2013-07-29 3 views
1

В C# есть ли способ сопоставить один общий тип другому родовому типу во время компиляции? Я бы хотел избежать использования Reflection для этого вопроса. Например, скажем, я хотел бы иметь карту TypeA к TypeB, и что-то похожее на следующий код работы:Сопоставление обобщенного типа без отражения

private void List<U> GetItemList<T>() where T : class <== U is the destination type obtained by the compile-time mapping from T to U 
{ 
    Type U = GetMappedType(typeof(T)) <=== this needs to happen during compile-time 
    List<U> returnList = Session.QueryOver<U>().List(); 
    return returnList; 
} 

private Type GetMappedType(Type sourceType) 
{ 
    if (sourceType == typeof(TypeA)) 
     return typeof(TypeB); 
} 

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

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

В качестве побочного вопроса, если я действительно использую Reflection для этого, сделает ли он реализацию очень ресурсоемкой?

+0

Что именно вы хотите достичь? – dmay

+0

@dmay Я создаю слой репозитория для моего приложения как такового: [Уровень домена <==> Слой репозитория (с типами NHibernate) <==> DB]. Мне нужна функция, которая принимает тип домена и Func и выводит список типов доменов, соответствующих функции. Проблема в том, что с помощью NHibernate я не могу запросить с входящим типом домена, я должен запросить с соответствующим типом репозитория. У меня есть функция, которая отображает мои типы доменов в типы NHibernate. Поэтому мне сначала нужно преобразовать свой тип домена в тип NHibernate, а затем запросить NHibernate, используя полученный NH-тип. (contd ...) – Anshul

+0

(... contd) Поэтому по существу я должен использовать динамический тип в качестве типичного параметра типа. Я думаю, что я нашел решение для этого, и это использует ключевое слово «dynamic», которое было введено в C# 4.0. Это позволяет компилятору существенно обходить безопасность типа на объекте (насколько я могу судить), потому что вы можете использовать его везде, где тип объекта будет динамически определяться. Тем не менее, я все еще проверяю это, поэтому я отправлю ответ здесь, как только я уверен. – Anshul

ответ

2

Да, был бы динамичным. Недавно у меня была такая же проблема, когда мне пришлось переключать репозитории на основе некоторых значений, настроенных в базе данных.

var tableNameWithoutSchema = tableName.Substring(tableName.IndexOf(".", StringComparison.Ordinal) + 1); 
var tableType = string.Format("Library.Namespace.{0}, Library.Name", tableNameWithoutSchema); 
var instance = UnitofWork.CreateRepository(tableType, uoW); 

CreateRepository возвращает динамический тип

public static dynamic CreateRepository(string targetType, DbContext context) 
{ 
    Type genericType = typeof(Repository<>).MakeGenericType(Type.GetType(targetType)); 
    var instance = Activator.CreateInstance(genericType, new object[] { context }); 
    return instance; 
} 

контекст был необходим, поскольку я должен был передать контекст Generic хранилище через конструктор. В моем случае этот подход имел некоторые проблемы. Может быть, это поможет вам.

+0

Какие у вас проблемы с этим подходом, если вы не возражаете, чтобы я спросил? Потому что я думаю, что я иду по тому же пути. – Anshul

+0

Проблема заключалась в том, что мне пришлось использовать лямбда для фильтрации некоторых записей, но вы не можете использовать лямбда с динамическими объектами. – Nilesh

+0

Не можете ли вы просто применить динамику к своему типу и использовать лямбда? – Anshul

Смежные вопросы