Double Possible:
Quelqu'un connais une bonne solution de contournement pour le manque d'un enum contrainte générique?Quelle est la raison derrière C# ne permettant pas de contraintes de type sur
Enum
's? Je suis sûr qu'il y est une méthode derrière la folie, mais je voudrais comprendre pourquoi il n'est pas possible.Ci-dessous est ce que je voudrais être en mesure de le faire (en théorie).
public static T GetEnum<T>(this string description) where T : Enum { ... }
Réponses
Trop de publicités?En fait, c'est possible, avec un truc moche. Cependant, il ne peut pas être utilisé pour les méthodes d'extension.
public abstract class Enums<Temp> where Temp : class {
public static TEnum Parse<TEnum>(string name) where TEnum : struct, Temp {
return (TEnum)Enum.Parse(typeof(TEnum), name);
}
}
public abstract class Enums : Enums<Enum> { }
Enums.Parse<DateTimeKind>("Local")
Si vous le souhaitez, vous pouvez donner à Enums<Temp>
un constructeur privé et une classe héritée abstraite publique imbriquée avec Temp
as Enum
, pour empêcher les versions héritées des non-énumérations .
Notez que vous ne pouvez pas utiliser cette astuce pour créer des méthodes d'extension.
C'est une occasion de demande de fonctionnalité.
Comme je suis friand de souligner, TOUTES les fonctionnalités sont mises au placard jusqu'à ce que quelqu'un les dessins, les spécifications, les instruments, les tests, les documents et les navires de la fonctionnalité. Jusqu'à présent, personne ne l'a fait que pour celui-ci. Il n'y a pas particulièrement inhabituel pourquoi pas; nous avons beaucoup d'autres choses à faire, des budgets limités, et celui-ci n'a jamais passé le "ne serait-ce pas agréable?" discussion dans la langue de l'équipe de conception.
Le CLR ne le supporte pas, donc pour le faire fonctionner, nous aurions besoin de faire d'exécution des travaux en plus de la langue de travail. (voir la réponse des commentaires)
Je peux voir qu'il y a quelques décent cas d'utilisation, mais aucun d'entre eux sont si convaincants que nous venions de faire ce travail plutôt que de l'une des centaines d'autres fonctionnalités qui sont beaucoup plus fréquemment demandés, ou qui ont plus convaincants et les plus ambitieuses cas d'utilisation. (Si nous allons à la boue avec ce code, je serais personnellement prioriser délégué contraintes façon, de manière au-dessus de l'enum de contraintes).
Voici une version VB.NET SLaks excellent truc laid, avec `` comme « typedef » : (inférence de Type fonctionne comme prévu, mais vous ne pouvez pas obtenir les méthodes d’extension.)
Sortie :
Un excentrique, c'est ici qu'il y a un bon nombre de génériques Enum méthodes que vous pourriez écrire dont la mise en œuvre dépend de la "base", le type de l'énumération.
Par la "base" type d'une énumération, E
, je veux dire le type en System
de l'espace de noms dont le nom est le même que le nom du membre de la System.TypeCode
énumération obtenu en appelant System.Type.GetTypeCode(System.Type)
pour le type E
. Si le comptage a été déclarée en C#, c'est le même type qu'il a été déclaré "hériter" de l' (je ne suis pas sûr de ce qui est officiellement appelé dans les specs). Par exemple, le type de base de l' Animal
énumération ci-dessous est - System.Byte
:
public enum Animal : byte
{
Moose,
Squirrel
}
Il est possible d'écrire de telles méthodes à l'aide de l'interrupteur d'instructions, mais c'est sûr qu'il est laid, vous ne pouvez pas fortement typé paramètres ou des types de retour dont le type est le type de base de l'énumération, et vous devez répéter les métadonnées de recherche ou pour faire de la mise en cache (par exemple dans le constructeur statique pour le type générique contenant la méthode).