Comment puis-je utiliser l'interface comme un C# de type générique de contrainte?
Est-il un moyen d'obtenir la déclaration de fonction suivante?
public bool Foo<T>() where T : interface;
ie. où T est un type d'interface (similaire à where T : class
, et struct
).
Actuellement, j'ai installé pour:
public bool Foo<T>() where T : IBase;
Où IBase est définie comme une interface vide qui est hérité par tous mes interfaces personnalisées... Pas l'idéal, mais il devrait fonctionner... Pourquoi ne peut-on pas définir un type générique doit être une interface?
Pour ce que ça vaut, je la veux parce que Foo
est en train de faire de réflexion où il a besoin d'un type d'interface... j'ai pu passer comme une normale de paramètres et de faire le nécessaire de vérifier dans la fonction elle-même, mais cela semblait beaucoup plus typesafe (et, je suppose, un peu plus performant, puisque tous les contrôles sont effectués à l'compile-time).
- En fait, votre IBase dea est le meilleur que j'ai vu jusqu'à présent. Malheureusement, vous ne pouvez pas l'utiliser pour les interfaces ne vous appartient pas. Tous les C# serait d'avoir toutes les interfaces hériter de IOjbect comme toutes les classes héritent de l'Objet.
Vous devez vous connecter pour publier un commentaire.
Le plus proche que vous pouvez faire (sauf pour votre base-approche de l'interface) est "
where T : class
", dans le sens de référence-type. Il n'y a pas de syntaxe pour dire "interface".Ce ("
where T : class
") est utilisé, par exemple, dans WCF pour limiter les clients pour des contrats de service (interfaces).interface
contrainte surT
devrait permettre de référence des comparaisons entre lesT
et tout autre type de référence, puisque la référence des comparaisons sont autorisés entre l'interface et presque tout autre type de référence, et de permettre des comparaisons de même que les cas ne poserait pas de problème.Je sais c'est un peu tard, mais pour ceux qui sont intéressés, vous pouvez utiliser un moment de l'exécution.
Foo(Type type)
.if (new T() is IMyInterface) { }
pour vérifier si une interface est implémentée par la classe T. Peut-être pas la plus efficace, mais il fonctionne.Non, en fait, si vous envisagez
class
etstruct
direclass
es etstruct
s, vous avez tort.class
signifie tout type de référence (par exemple, intègre des interfaces trop) etstruct
signifie tout type de valeur de (par exemplestruct
,enum
).where T : struct
contrainte.class
, mais déclarant un emplacement de stockage d'un type d'interface vraiment déclare l'emplacement de stockage à une classe de référence qui mettent en œuvre ce type.where T : struct
correspond àNotNullableValueTypeConstraint
, ainsi il signifie qu'il doit être une valeur de type autres queNullable<>
. (DoncNullable<>
est un type struct qui ne satisfait pas lewhere T : struct
contrainte.)De suivi sur Robert réponse, c'est encore plus tard, mais vous pouvez utiliser une statique de la classe helper pour rendre le moment de l'exécution qu'une seule fois par type:
Je note aussi que votre "doit travailler" la solution n'est pas, en effet, le travail. Considérer:
Maintenant il n'y a rien qui vous empêche d'appeler Foo ainsi:
La
Actual
classe, après tout, s'il satisfait à laIBase
contrainte.static
constructeur ne peut pas êtrepublic
, ce qui donne une erreur de compilation. Aussi votrestatic
classe contient une méthode d'instance, c'est une erreur de compilation ainsi.Vous ne pouvez pas faire cela dans n'importe quel version de C#, ni dans le prochain C# 4.0. Ce n'est pas un C# limitation, - il n'y a pas "d'interface" contrainte dans le CLR lui-même.
Si possible, je suis allé avec une solution de ce genre. Il ne fonctionne que si vous voulez plusieurs interfaces spécifiques (par exemple, ceux que vous avez accès à la source d') pour être transmis en tant que paramètre générique, pas du tout.
IInterface
.IInterface
Dans la source, il ressemble à ceci:
N'importe quelle interface vous voulez être transmis en tant que paramètre générique:
IInterface:
La classe sur laquelle vous souhaitez placer une contrainte de type:
Ce que vous avez arrangé pour est le meilleur que vous pouvez faire:
J'ai essayé de faire quelque chose de similaire et utilisé une solution de rechange: j'y ai pensé implicite et explicite de l'opérateur sur la structure: L'idée est d'envelopper le Type de structure qui peut être converti en Type de données implicitement.
Ici est d'une telle structure:
public struct InterfaceType
{
Type privé _type;
}
d'utilisation de base:
Vous devez imaginer votre propre mécanisme de contourner cela, mais, par exemple, pourrait être une méthode pris un InterfaceType en paramètre à la place d'un type
Une méthode pour remplacer la qui devrait retourne types d'interface:
Il y a peut-être des choses à faire avec les génériques, mais je n'ai pas essayé
Espère que cela peut vous aider ou donne des idées 🙂
Utilisation d'une classe abstraite à la place. Donc, vous auriez quelque chose comme: