2009-11-14 15 views
8

Je veux créer une simple fonction génériqueC#: Comment utiliser la méthode générique "out" variables

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

Utilisation:

int value; 
string text; 

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

Ma question est comment le programme vous le code pour définir ces valeurs ie. les codes manquants dans la section des commentaires.

Merci pour toute aide.

Répondre

16

On dirait que dans ce cas peut-être que vous le faites pour essayer d'éviter la boxe? Difficile à dire sans plus d'informations, mais pour cet exemple précis, ce serait beaucoup plus facile et probablement moins sujettes aux bugs juste utiliser la surcharge de la méthode:

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

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

Aux fins de l'apprentissage précisément ce que est mal ici , vous avez besoin d'associer une valeur à un objet avant la coulée au type générique:

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

dont l'OMI est assez méchant et devrait être un dernier recours - ne certainement pas votre code un produit de nettoyage.

Chaque fois que vous faites un contrôle de type de paramètres génériques, c'est une bonne indication que les génériques ne sont pas la bonne solution à votre problème. Effectuer des vérifications de type de paramètre génériques rend votre code plus complexe, pas plus simple. Il rend une méthode responsable de différents comportements basés sur le type, au lieu d'une série de méthodes simples qui sont faciles à changer sans affecter accidentellement les autres. Voir Single Responsibility Principle.

0

Voici une façon:

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

Mais ce code sent vraiment mauvais et va à l'encontre du point de génériques (au lieu d'utiliser les méthodes surchargées). J'espère que cela ne finira pas dans le code de production et ne servira qu'à l'édification.

+0

Merci beaucoup; cela marche. La raison pour laquelle j'utilise une approche générique est de simplifier mon code. Parce que le "code d'assignation" est seulement nécessaire pour un type spécifique (par exemple une chaîne); il serait mauvais de créer des fonctions surchargées pour tous les types possibles là-bas. Résultat = défaut (T) // est le comportement courant –

+7

Je ne suis pas d'accord avec vous. Je pense que la surcharge est exactement pour ça. Utilisez des génériques uniquement lorsque cela est nécessaire. – Sheldon

3

Tout d'abord, c'est un très mauvais modèle. Vous ne devriez pas utiliser ce genre de motif. Peut-être que si vous décrivez ce que vous voulez vraiment réaliser, il y aura de meilleures réponses. Le code ci-dessous fonctionne, mais comme je l'ai dit, écrire du code de cette façon est une mauvaise idée.

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

et utilisation:

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