2009-04-20 4 views
0

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

... 
Type type = ...; 
Type interfaceType = someOtherType.GetInterface("IConverter`2"); 

return (Cast to interfaceType)Activator.CreateInstance(type); 

Возможно ли отливка от интерфейса?

Update:

Компилятор говорит, что T и K не могут быть найдены. Экземпляр MyInterface Тип знает T и класс K ...

public IConverter<T, K> GetConverter(Type type) 
{ 
    if (dtoModelDictionary.ContainsKey(type)) 
    { 
     Type foundType = dtoModelDictionary[type]; 
     Type myInterface = foundType.GetInterface("IConverter`2"); 

     return (IConverter<T, K>)Activator.CreateInstance(foundType); 
    } 
    else if (dalModelDictionary.ContainsKey(type)) 
    { 
     Type foundType = dalModelDictionary[type]; 

     return (IConverter<T, K>)Activator.CreateInstance(foundType); 
    } 
    else 
    { 
     throw new System.Exception(); 
    } 
} 

Второе обновление:

public SomeClass GetConverter(Type type) 
    { 
     if (dtoModelDictionary.ContainsKey(type)) 
     { 
      Type foundType = dtoModelDictionary[type]; 
      Type myInterface = foundType.GetInterface("IConverter`2"); 

      IConverter<T, K> converter = (IConverter<T, K>)Activator.CreateInstance(foundType); 
      return converter.someMethod(); 
     } 
    } 

ответ

3

Ответ вам обновить:

Вы не можете преобразовать тип, в котором общие аргументы не определены. T и K должны быть определены для метода, который его использует.

Либо объявить:

public IConverter<T, K> GetConverter<T, K>(Type type) 

Или, если вы столкнулись с проблемой часто, что используется этот интерфейс, но вы не знаете, какие T или K типа, используют интерфейс без дженериков:

interface IConverter 
{ 
    // general members 
} 

interface IConverter<T, K> : IConverter 
{ 
    // typesave members 
} 

public IConverter GetConverter(Type type) 
{ 
    // ... 
    return (IConverter)Activator.CreateInstance(type); 
} 
+0

Хорошо, я попробую это, но что, если я хочу вызвать метод из второго интерфейса (typesave members)? (см. новое обновление). спасибо. –

+0

Вы не можете вызывать типы типов, не зная типов. Если вы их знаете, вы можете отправить его на соответствующий IConverter . Но лучше предоставить все в общем интерфейсе IConverter, который должен быть доступен, не зная типов. У меня иногда есть свойства типа 'object UntypedValue {get; } ', чтобы обеспечить доступ к значениям, не зная тип. Таким образом, правило: используйте T и K всякий раз, когда вы их знаете, но предоставляйте способ делать все, не зная их. –

1

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

Теперь, если вы используете генериков, вы сделать имеют историю набрав во время выполнения, вы можете вернуть их тип параметра:

public T MyMethod<T>(...) 
... 
return (T)Activator.CreateInstance(type); 
+0

Thx, я обновил вопрос с некоторым кодом. Ваше возвращение (T) - это то, что мой компилятор не нравится, потому что он говорит, что тип или пространство имен T не может быть найдено. –

1

Вы можете только бросить объект на то, что оно на самом деле , Вы можете, например, направить String ссылку на IEnumerable, но вы не можете отдать ее char[].

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

Пример:

return (IConverter<int,string>)Activator.CreateInstance(type); 

Edit:
Вам нужно сделать метод родовым, так что вы можете указать типы данных, когда вы называете его:

public IConverter<T, K> GetConverter<T, K>(Type type) { 
    ... 
} 
+0

Это просто проблема. Я не знаю во время компиляции, что Т и К будут ... –

+0

Если вы не знаете тип во время компиляции, вы не можете объявить переменную с этим типом для хранения ссылки, поэтому бессмысленно делать актерский состав. – Guffa

1

Вы можете сделать это:

var type = typeof(IConverter<,>).MakeGenericType(new Type[] { typeof(T), typeof(K) }); 
Смежные вопросы