C # Utilisez les génériques et les arbres d'expression pour obtenir les valeurs de champs d'objet

.net c# expression-trees

Question

J'ai deux classes avec des champs similaires:

Class Foo {
    string name;
    int val;
};

Class Bar {
    string name;
    int val;
};

Existe-t-il un moyen d’utiliser Generics pour récupérer les noms de champs et les valeurs des objets de ces classes? Quelque chose dans le genre de:

Class Foo {
    string name;
    int val;
};

Class Bar {
    string name;
    int val;
};

Je veux m'assurer qu'il y a des contrôles de temps de compilation pour cela, au cas où les champs de la classe devaient changer.

Mettre à jour:

Je ne contrôle pas les définitions des classes Foo et Bar. Ils seront exposés à moi dans une bibliothèque et peuvent changer.

Je peux utiliser quelque chose comme ce qui suit:

Class Foo {
    string name;
    int val;
};

Class Bar {
    string name;
    int val;
};

Mais je ne pense pas que cela vérifierait au moment de la compilation.

Réponse acceptée

Si vous voulez une sécurité au moment de la compilation et que vous ne pouvez pas modifier Foo and Bar , le moyen typique de gérer cela est avec des surcharges :

public string GetName(Foo o) { return o.Name; }
public string GetName(Bar o) { return o.Name; }

Le compilateur choisit automatiquement la méthode qui correspond au type du paramètre, il vous suffit donc de l’appeler avec

public string GetName(Foo o) { return o.Name; }
public string GetName(Bar o) { return o.Name; }

... et c'est sûr.

Vous ne pouvez pas vraiment utiliser les génériques car Foo et Bar n'ont pas d'interface commune exposant Name .

Vous pouvez utiliser Reflection, bien sûr, mais cela signifie abandonner la sécurité au moment de la compilation.


Réponse populaire

Cela semble être un cas où vous pourriez utiliser l'héritage. Si ces deux classes ont des champs similaires, vous pouvez leur faire implémenter une classe de base contenant tous les champs partagés. Voici un exemple:

public class BaseEntity
{
    int val;
    protected string name;
    public string Name
    {
        get
        {
            return name; // Only get is exposed to prevent modifications
        }
    }
}

public class ClassA : BaseEntity
{
   // Other fields or methods
}

public class ClassB : BaseEntity
{
    // Other fields or methods
}



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi