Existe-t-il un moyen d'imposer/limiter les types qui sont transmis aux primitives ? (bool, int, string, etc.)
Maintenant, je sais que vous pouvez limiter le paramètre de type générique à un type ou à une implémentation d'interface via la fonction où clause. Cependant, cela ne convient pas aux primitives (AFAIK) car elles n'ont pas toutes un point commun (à l'exception des objet avant que quelqu'un ne le dise ! :P).
Donc, mes pensées actuelles sont de serrer les dents et de faire un gros commutateur et lancer un ArgumentException en cas d'échec.
EDIT 1 :
Juste pour clarifier :
La définition du code devrait être comme ceci :
public class MyClass<GenericType> ....
Et l'instanciation :
MyClass<bool> = new MyClass<bool>(); // Legal
MyClass<string> = new MyClass<string>(); // Legal
MyClass<DataSet> = new MyClass<DataSet>(); // Illegal
MyClass<RobsFunkyHat> = new MyClass<RobsFunkyHat>(); // Illegal (but looks awesome!)
EDIT 2
@Jon Limjap - Bon point, et quelque chose que je considérais déjà. Je suis sûr qu'il existe une méthode générique qui peut être utilisée pour déterminer si le type est de type valeur ou référence.
Cela pourrait être utile pour supprimer instantanément un grand nombre d'objets dont je ne veux pas m'occuper (mais il faut alors se préoccuper des structs utilisés tels que Taille ). Un problème intéressant non ? :)
C'est ici :
where T: struct
Tiré de MSDN .
Je suis curieux. Est-ce que cela pourrait être fait dans .NET 3.x en utilisant des méthodes d'extension ? Créer une interface, et implémenter l'interface dans les méthodes d'extension (ce qui serait probablement plus propre qu'un commutateur un peu gros). De plus, si vous avez besoin d'étendre ultérieurement à des types personnalisés légers, ils peuvent également mettre en œuvre la même interface, sans qu'il soit nécessaire de modifier le code de base.
Qu'est-ce que vous en pensez ?
La triste nouvelle, c'est que je travaille dans le Framework 2 ! !! :D
EDIT 3
C'était si simple, suite à Jon Limjaps Pointer .. Si simple que j'ai presque envie de pleurer, mais c'est génial car le code fonctionne comme un charme !
Voici donc ce que j'ai fait (vous allez rire !) :
Code ajouté à la classe générique
bool TypeValid()
{
// Get the TypeCode from the Primitive Type
TypeCode code = Type.GetTypeCode(typeof(PrimitiveDataType));
// All of the TypeCode Enumeration refer Primitive Types
// with the exception of Object and Empty (Null).
// Since I am willing to allow Null Types (at this time)
// all we need to check for is Object!
switch (code)
{
case TypeCode.Object:
return false;
default:
return true;
}
}
Puis une petite méthode utilitaire pour vérifier le type et lancer une exception,
private void EnforcePrimitiveType()
{
if (!TypeValid())
throw new InvalidOperationException(
"Unable to Instantiate SimpleMetadata based on the Generic Type of '" + typeof(PrimitiveDataType).Name +
"' - this Class is Designed to Work with Primitive Data Types Only.");
}
Il suffit alors d'appeler EnforcePrimitiveType() dans les constructeurs des classes. C'est fait ! :-)
Le seul inconvénient est qu'il ne lève une exception qu'au moment de l'exécution (évidemment) plutôt qu'au moment de la conception. Mais ce n'est pas un gros problème et peut être récupéré avec des utilitaires comme FxCop (que nous n'utilisons pas au travail).
Un grand merci à Jon Limjap sur ce coup-là !
0 votes
Vous pouvez également appeler la vérification dans votre constructeur statique, afin qu'elle ne soit appelée qu'une seule fois par type utilisé comme argument générique.