C# Génériques ne permettent pas à Déléguer les Contraintes de Type
Est-il possible de définir une classe en C#, tels que
class GenericCollection<T> : SomeBaseCollection<T> where T : Delegate
Je ne pouvais pas pour la vie de m'accomplir cette dernière nuit .NET 3.5. J'ai essayé d'utiliser
delegate, Delegate, Action<T> and Func<T, T>
Il me semble que cela devrait être permis, d'une certaine façon. Je suis en train de mettre en place mes propres EventQueue.
J'ai juste le faire [primitive rapprochement que vous avez l'esprit].
internal delegate void DWork();
class EventQueue {
private Queue<DWork> eventq;
}
Mais je perds la possibilité de réutiliser la même définition pour les différents types de fonctions.
Pensées?
Vous devez vous connecter pour publier un commentaire.
Un certain nombre de classes sont disponibles comme générique contraintes - Enum est un autre.
Pour les délégués, le plus proche que vous pouvez obtenir est: "classe", peut-être à l'aide de la réflexion afin de vérifier (par exemple, dans le constructeur statique) que le T est un délégué:
CA1065: Do not raise exceptions in unexpected locations
... j'étais toujours dans l'hypothèse que vous devez utiliser un code personnalisé de règles d'analyse pour trouver des invalides usages de votre classe qui ne sont normalement pas disponibles au moment de l'exécution.where T : Delegate
, (et quelqu'un a publié une nouvelle réponse à ce sujet ci-dessous).Edit: Certains ont proposé des solutions de rechange sont proposées dans ces articles:
http://jacobcarpenters.blogspot.com/2006/06/c-30-and-delegate-conversion.html
http://jacobcarpenters.blogspot.com/2006_11_01_archive.html
De la C# 2.0 on peut lire (20.7, Contraintes):
Une classe de type de contrainte doivent satisfaire aux règles suivantes:
Et bien sûr VS2008 crache une erreur:
Pour l'info et enquête sur cette question, lire ici.
Si vous êtes prêt à prendre un moment de la compilation de dépendance sur un IL Weaver vous pouvez faire cela avec Fody.
À l'aide de cet addin pour Fody https://github.com/Fody/ExtraConstraints
Votre code peut ressembler à ceci
Et être compilé à ce
Oui c'est possible en C# 7.3, les Contraintes de la famille a augmenté pour inclure
Enum
,Delegate
etunmanaged
types.Vous pouvez écrire ce code sans problème:
Liens utiles:
L'avenir de C#, à partir de Microsoft Build 2018
Les nouveautés de C# 7.3?
Délégué prend déjà en charge de chaînage. N'est-ce pas répondre à vos besoins?
Je suis tombé sur une situation où j'avais besoin de traiter avec un
Delegate
à l'intérieur, mais je voulais une contrainte générique. Plus précisément, je voulais ajouter un gestionnaire d'événement à l'aide de la réflexion, mais je voulais utiliser un argument générique pour le délégué. Le code ci-dessous ne fonctionne PAS, depuis le "Gestionnaire" est un type de variable, et le compilateur ne jette pasHandler
àDelegate
:Cependant, vous pouvez passer une fonction qui fait la conversion pour vous.
convert
prend unHandler
argument et renvoie unDelegate
:Maintenant que le compilateur est heureux. L'appel de la méthode est facile. Par exemple, en joignant à la
KeyPress
événement sur un contrôle Windows Forms:où
SomeControl_KeyPress
est la cible de l'événement. La clé est le convertisseur de lambda - il n'a pas de travail, mais il convainc le compilateur vous lui avez donné un valide délégué.(Commencer 280Z28) @Justin: Pourquoi ne pas l'utiliser?
(Fin 280Z28)
Comme mentionné ci-dessus, vous ne pouvez pas avoir les Délégués et les Enum comme une contrainte générique.
System.Object
etSystem.ValueType
aussi ne peut pas être utilisé comme une contrainte générique.Le travail autour de peut être, si vous construisez un appel approprié en vous IL. Cela fonctionnera très bien.
Ici est un bon exemple de Jon Skeet.
http://code.google.com/p/unconstrained-melody/
J'ai pris mes références de Jon Skeet du livre C# en Profondeur, 3e édition.
Selon MSDN
Erreur du compilateur CS0702
Contrainte ne peut pas être classe spéciale " identifier Les types suivants ne peuvent pas être utilisés comme des contraintes: