1
votes

Pouvez-vous obtenir un comportement spécifique à un type à partir de génériques en c #?

Je pense que ce que je veux faire devrait être assez clair - obtenir une spécialisation explicite pour int et string , et en C ++, c'est trivial avec une spécialisation explicite - c'est -il possible d'obtenir ce même comportement en C #? Supposons que j'ai une bonne raison de faire cela et que ceci est un exemple trivial de quelque chose de plus large dans mon programme.

template <typename T>
T giveConst();
template <>
int giveConst<int>() { return 5; }
template <>
std::string giveConst<std::string>() { return "Hello"; }

Edit:

Voici l'équivalent du code C ++ parfaitement légitime :

static class ReturnConstant<T>
{
    public static T FiveOrHello()
    {
        if(typeof(T) == typeof(int))
        {
            return 5;
        }
        else if (typeof(T) == typeof(string))
        {
            return "Hello!";
        }
        else
        {
            throw new NotImplementedException("OH NO");
        }
    }
}


3 commentaires

Supposons que j'ai une bonne raison de faire cela et que ceci est un exemple trivial de quelque chose de plus large dans mon programme. , en ignorant cette phrase, qu'essayez-vous de faire? Il doit y avoir une meilleure solution.


J'ai une chose qui prend des paramètres et retourne une datatable générique, en C ++, j'ai une autre chose qui prend cette datatable générique et renvoie des informations typées, en C ++ je modéliserais cette première chose et la ferais faire la conversion automatiquement comme ci-dessus.


Vous devriez éloborer là-dessus alors. Votre base de données n'est pas générique, si elles ont des types différents. C'est un n'importe quel objet ou mieux objet . On dirait que vous avez vraiment besoin de moulages et probablement une couche qui gère différents types d'objets vérifiés via est . De toute façon sans vrai code, il est difficile de donner des conseils.


3 Réponses :


0
votes

Non, c'est impossible. Le T générique pour la classe ReturnConstant signifie que ReturnConstant et ReturnConstant sont différents les types. Et vous ne pouvez pas renvoyer différents types en commun.


1 commentaires

Ah, donc parce qu'il est résolu au moment de l'exécution, il s'agit d'un problème de type ne peut pas différencier basé sur le type de retour uniquement?



3
votes

Le seul problème avec votre implémentation est que le compilateur C # ne peut pas vérifier le type converti en T.

Mais vous pouvez contourner cela comme ceci:

static class ReturnConstant<T>
{
    public static T FiveOrHello()
    {
        if (typeof(T) == typeof(int))
        {
            return (T)(object)5;
        }
        else if (typeof(T) == typeof(string))
        {
            return (T)(object)"Hello!";
        }
        else
        {
            throw new NotImplementedException("OH NO");
        }
    }
}


2 commentaires

Oh chouette! Quelle est la fonction de (objet) ici - est-ce comme typename en C ++?


object est un type, et c'est la racine de la hiérarchie des types .NET. Je ne connais pas l'historique, mais je suppose que comme aucune conversion de type de objet vers un autre type ne peut être validée par le compilateur, la validation est désactivée. Et le transtypage via objet est devenu un idiome pour effectuer une conversion de type non vérifiée à la compilation.



0
votes

Un concept qui pourrait vous intéresser est celui d'une union discriminée; cela vous permettrait de renvoyer un entier ou une chaîne avec un seul type, mais vous devrez vérifier au moment de l'exécution pour déterminer lequel a réellement été retourné:

Malheureusement, le concept n'existe pas actuellement d'une manière qui puisse être efficacement implémentée, nécessitant une prise en charge linguistique, qui n'est pas encore ajoutée.

https://github.com/dotnet/csharplang/issues/113


0 commentaires