2009-04-20 23 views
0

Ich frage mich, ob es möglich ist, ein Objekt zu einem Typ zu werfen ... Ich habe gerade angefangen, Reflection zu verwenden, also mache ich vielleicht alles falsch, aber hier ist, was ich tun möchte:Casting zu einem Typ

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

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

Ist die Umwandlung in die Schnittstelle möglich?

Update:

Compiler sagt, dass T und K kann nicht gefunden werden. Die myInterface Typ Instanz kennt die T und K-Klasse ...

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(); 
    } 
} 

Zweites Update:

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(); 
     } 
    } 

Antwort

3

Antwort Sie aktualisieren:

Sie können nicht in einen Typ umwandeln, in dem die generischen Argumente nicht definiert sind. T und K müssen für die Methode definiert sein, die sie verwendet.

Entweder erklären sie:

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

Oder, wenn Sie das Problem oft vor, dass diese Schnittstelle verwendet wird, aber Sie wissen nicht, keine T oder K-Typen, verwenden Sie eine Schnittstelle ohne Generika:

interface IConverter 
{ 
    // general members 
} 

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

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

Ok, ich werde das versuchen, aber was, wenn ich eine Methode aus der zweiten Schnittstelle (typesave Mitglieder) auslösen möchte? (siehe neues Update). Danke. –

+0

Sie können typesave-Member nicht aufrufen, ohne die Typen zu kennen. Wenn Sie sie kennen, können Sie sie in den entsprechenden IConverter umwandeln. Aber es ist besser, alles in der allgemeinen IConverter-Schnittstelle bereitzustellen, die verfügbar sein muss, ohne die Typen zu kennen. Ich habe manchmal Eigenschaften wie 'object UntypedValue {get; } 'um Zugriff auf Werte zu ermöglichen, ohne den Typ zu kennen. Die Regel lautet also: Benutze T und K, wann immer du sie kennst, aber gib ihnen einen Weg, alles zu tun, ohne sie zu kennen. –

1

Nicht wirklich, nein ... zumindest nicht auf diese Weise. Das Problem besteht darin, dass der Rückgabewert unabhängig vom Rückgabewert der Methode angegeben werden muss. Da zur Kompilierungszeit alles eingegeben werden muss, gibt es nur einen begrenzten oder keinen echten Anwendungsfall, den ich für diese bestimmte Art von Typ-Coversion sehen kann - vielleicht können Sie etwas mehr über das sagen, was Sie erreichen wollen?

Nun, wenn Sie Generika verwenden, Sie zu tun haben eine Laufzeit-Typisierung Geschichte, können Sie Ihren Typ Parametertyp zurück:

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

Thx, habe ich die Frage mit einigen Code aktualisiert. Ihre Rückgabe (T) ist, was mein Compiler nicht mag, weil es besagt, dass der Typ oder der Namespace T nicht gefunden werden kann. –

1

Sie nur ein Objekt zu etwas werfen kann, dass es tatsächlich ist . Sie können beispielsweise einen String Verweis auf IEnumerable referenzieren, aber Sie können ihn nicht auf char[] umwandeln.

Wenn das, was Ihre Methode zurückgibt, tatsächlich die Schnittstelle implementiert, können Sie sie einfach wie gewohnt umwandeln.

Beispiel:

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

Edit:
Sie müssen die Methode generisch machen, so dass Sie die Datentypen angeben können, wenn Sie es nennen:

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

Das ist nur das Problem. Ich weiß zur Kompilierzeit nicht, was T und K sein werden ... –

+0

Wenn Sie den Typ zum Zeitpunkt der Kompilierung nicht kennen, können Sie keine Variable mit diesem Typ deklarieren, in der der Verweis gespeichert werden soll. Daher ist es sinnlos, eine Umwandlung durchzuführen. – Guffa

1

Sie können dies tun:

var type = typeof(IConverter<,>).MakeGenericType(new Type[] { typeof(T), typeof(K) });