2012-07-25 5 views
6

Ich implementiere eine Schnittstelle, um benutzerdefinierte Geschäftslogik in ein Framework zu injizieren, das Microsoft Unity verwendet. Mein Kernproblem ist, dass eine der Schnittstelle Ich brauche die folgende Methode zur Implementierung definiert:Implementieren einer Schnittstelle mit einem generischen Typ, der weniger eingeschränkt ist als der einer Methode, die ich aufrufen muss

T InterfaceMethod<T>(); 

T keine Einschränkungen haben. In meinem Code, ich brauche aus einer anderen 3rd-Party-Bibliothek, ein Verfahren zu nennen, mit einer Methodensignatur von

T AnotherMethod<T>() where T: class; 

Der Typ T ist signifikant für die Logik der AnotherMethod. Gibt es eine Möglichkeit, AnotherMethod<T>() innerhalb meiner Implementierung aufzurufen, ohne Reflektion zu verwenden? Ich muss natürlich eine alternative Aktion durchführen, wenn T ein Werttyp ist. Gibt es vielleicht einen Weg zur Autobox, um das zu umgehen?

+0

Was bedeutet AnotherMethod () tun mit T? Wenn Sie es boxen wollen, werfen Sie es einfach vorher auf ein Objekt ..? –

+0

Nicht sicher, dass es mir hilft, da ich einen Kompilierungsfehler bezüglich T erhalte, der ein Bezugstyp sein muss. – techphoria414

Antwort

1

Ich glaube nicht, dass das, was Sie suchen, ohne Reflexion möglich ist. Im besten Fall könntest du einfach AnotherMethod<object>() anrufen und das Ergebnis gießen. Aber das würde nur richtig funktionieren, wenn AnotherMethod 's T nicht für Ihre Zwecke wichtig ist.

+0

Es scheint, dass Sie in meinem Fall richtig sind. – techphoria414

2

Ich bin nicht sicher, dass dies genau das ist, was Sie brauchen, aber dies ermöglicht Ihnen, AnotherMethod von InterfaceMethod aufzurufen, ohne Reflektion zu verwenden. Es verwendet jedoch immer noch einen Convert.ChangeType.

Die Idee ist, die Implementierung der Klasse generisch mit einem Constrain (hier Tin) zu machen. Dann konvertieren Sie den unbeschränkten Typ T der InterfaceMethod in Tin. Schließlich können Sie das AnotherMethod mit dem eingeschränkten Typ aufrufen. Das Folgende funktioniert gut mit Strings.

public interface ITest 
{ 
    T InterfaceMethod<T> (T arg); 
} 

public interface ITest2 
{ 
    U AnotherMethod<U>(U arg) where U : class; 
} 

public class Test<Tin> : ITest, ITest2 where Tin : class 
{ 
    public T InterfaceMethod<T> (T arg) 
    { 
     Tin argU = arg as Tin; 
     if (argU != null) 
     { 
      Tin resultU = AnotherMethod(argU); 
      T resultT = (T)Convert.ChangeType(resultU,typeof(T)); 
      return resultT; 
     } 
     return default(T); 
    } 

    public U AnotherMethod<U> (U arg) where U : class { return arg; } 
} 
+0

+1 für Einfallsreichtum, aber leider mit der Art und Weise, wie meine Klasse von Unity im Framework-Code instanziiert werden muss, kann ich keine Generics für die Klasse selbst verwenden. Redigiert meine Frage, um die Situation ein wenig zu klären. Definitiv könnte für jemanden arbeiten, wo sie beim Instanziieren der Klasse angeben können. – techphoria414

0

Was die anderen sagen, ist, dass Sie durch das Objekt so gehen kann:

public interface ITest 
{ 
    T InterfaceMethod<T>(T arg); 
} 

public interface IAnotherTest 
{ 
    U AnotherMethod<U>(U arg) where U : class; 
} 

public class Test : ITest 
{ 
    private IAnotherTest _ianothertest; 

    public T InterfaceMethod<T>(T arg) 
    { 
     object argU = arg as object; 
     if (argU != null) 
     { 
      object resultU = _ianothertest.AnotherMethod(argU); 
      T resultT = (T)Convert.ChangeType(resultU, typeof(T)); 
      return resultT; 
     } 
     return default(T); 
    } 
} 
+0

Wie Tim S darauf hinweist, funktioniert das nur, wenn der Typ von T für die aufgerufene Methode nicht von Bedeutung ist. Leider ist es so. – techphoria414

Verwandte Themen