2009-11-14 8 views
8

Ich mag eine einfache generische Funktion erstellenC#: Wie generische Methode verwenden, um mit „out“ Variable

void Assign<T>(out T result) 
{ 
    Type type = typeof(T); 
    if (type.Name == "String") 
    { 
    // result = "hello"; 
    } 
    else if (type.Name == "Int32") 
    { 
    // result = 100; 
    } 
    else result = default(T); 
} 

Verbrauch:

int value; 
string text; 

Assign(value); // <<< should set value to 100 
Assign(text); // <<< should set text to "hello" 

Meine Frage ist, wie Sie den Code programmieren zu setzen diese Werte, dh. die fehlenden Codes im Kommentarbereich.

Danke für jede Hilfe.

Antwort

16

Es sieht so aus, als ob Sie in diesem Fall versuchen, das Boxen zu vermeiden? Schwierige ohne weitere Informationen zu sagen, aber für dieses spezifische Beispiel, wäre es viel einfacher und wahrscheinlich weniger fehleranfällig zu verwenden, nur eine Überlastung Methode:

void Assign(out string value) 
{ 
    //... 
} 

void Assign(out int value) 
{ 
    //... 
} 

Für die Zwecke des Lernens speziell was ist hier falsch , müssen Sie einen Wert auf ein Objekt werfen, bevor es den generischen Typen Gießen:

(T)(object)"hello world!"; 

Welche IMO ist ziemlich böse und soll ein letzter Ausweg - auf jeden Fall Ihren Code nicht jeden sauberer machen.

Jedes Mal, wenn Sie allgemeine generische Parameter typenüberprüfen, ist es eine gute Indikation Generika sind nicht die richtige Lösung für Ihr Problem. Generische Parameter-Typ-Prüfungen machen Ihren Code komplexer, nicht einfacher. Es macht eine Methode verantwortlich für verschiedene Verhaltensweisen, die auf dem Typ basieren, und nicht auf einer Reihe einzelner Methoden, die leicht geändert werden können, ohne die anderen zu beeinträchtigen. Siehe Single Responsibility Principle.

0

Hier ist eine Möglichkeit:

static void Assign<T>(out T result) { 
    Type type = typeof(T); 
    if (type.Name == "String") { 
     result = (T)Convert.ChangeType("hello", typeof(T)); 
    } 
    else if (type.Name == "Int32") { 
     result = (T)Convert.ChangeType(100, typeof(T)); 
    } 
    else { 
     result = default(T); 
    } 
} 

Aber dieser Code riecht wirklich schlecht und geht gegen den Punkt von Generika (statt überladene Methoden verwenden). Ich hoffe, dass dies nicht irgendwo im Produktionscode endet und nur der Erbauung dient.

+0

Vielen Dank; das funktioniert. Der Grund, warum ich generischen Ansatz verwende, ist, meinen Code zu vereinfachen. Weil der "assign code" nur für einen bestimmten Typ benötigt wird (zB string); Es wäre schlecht, überladene Funktionen für alle möglichen Arten dort draußen zu schaffen. Ergebnis = Standard (T) // ist das gemeinsame Verhalten –

+7

Ich stimme nicht mit Ihnen überein. Ich denke, Überladung ist genau dafür. Verwenden Sie Generika nur bei Bedarf. – Sheldon

3

Zunächst ist das ein sehr schlechtes Muster. Sie sollten diese Art von Muster nicht verwenden. Vielleicht, wenn Sie beschreiben, was Sie wirklich erreichen wollen, wird es bessere Antworten geben.

Code unten funktioniert, aber wie gesagt, Schreiben von Code auf diese Weise ist eine schlechte Idee.

void Assign<T>(out T result) 
    { 
     Type type = typeof(T); 
     if (type.Name == "String") 
     { result = (T) ((object)"hello"); } 
     else if (type.Name == "Int32") 
     { result = (T) ((object)100); } 
     else result = default(T); 
    } 

Und Nutzung:

 int value; 
     string text; 

     Assign(out value); 
     Assign(out text); 
1
public T GetObject<T>(string val) 
{ 
    T _object = default(T); 
    _object = (T)Convert.ChangeType(val, typeof(T)); 
    return _object; 
}