Puis-je ajouter une extension des méthodes à une classe statique?
Je suis un fan de méthodes d'extension en C#, mais je n'ai pas eu tout le succès de l'ajout d'une extension de la méthode à une classe statique, comme Console.
Par exemple, si je veux ajouter une extension à la Console, appelée "WriteBlueLine", de sorte que je peux aller:
Console.WriteBlueLine("This text is blue");
J'ai essayé en ajoutant un local, méthode statique publique, de la Console en tant que 'ce paramètre... mais pas de dés!
public static class Helpers {
public static void WriteBlueLine(this Console c, string text)
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine(text);
Console.ResetColor();
}
}
Cela n'a pas ajouter un "WriteBlueLine' méthode de la Console... suis-je le fais mal? Ou demander l'impossible?
- Oh bien. regrettable, mais je pense que je vais m'en sortir. Je suis ENCORE une extension de la méthode de la vierge (dans le code de production de toute façon). Peut-être un jour, si j'ai de la chance.
- J'ai écrit un certain nombre de HtmlHelper extensions pour ASP.NET MVC. A écrit un pour DateTime pour me donner la fin de la date donnée (23:59.59). Utile lorsque vous demandez à l'utilisateur de spécifier une date de fin, mais vraiment le vouloir pour être la fin de la journée.
- Il n'y a aucun moyen de les ajouter actuellement car la fonctionnalité n'existe pas en C#. Pas parce que c'est impossible en soi, mais parce que le C# peeps sont très occupés, étaient surtout intéressés par les méthodes d'extension pour faire LINQ travail et ne voit pas assez d'avantages statiques les méthodes d'extension pour justifier le temps qu'ils la prennent à mettre en œuvre. Eric Lippert explique ici.
- Évidemment tout à fait un certain nombre de gens veulent cette fonctionnalité, même si elle n'est pas actuellement possible. Vous pouvez voter à UserVoice pour la fonction à être mis en œuvre.
- Appelez simplement
Helpers.WriteBlueLine(null, "Hi");
🙂
Vous devez vous connecter pour publier un commentaire.
Pas. Les méthodes de vulgarisation nécessitent une variable d'instance (de la valeur) d'un objet. Toutefois, vous pouvez écrire un statique wrapper autour de la
ConfigurationManager
interface. Si vous mettez en œuvre le wrapper, vous n'avez pas besoin d'une extension de la méthode puisque vous pouvez simplement ajouter la méthode directement.null
pour un type de référence.Pouvez-vous ajouter de la statique des extensions de classes en C#? Non, mais vous pouvez le faire:
Voici comment cela fonctionne. Si vous ne pouvez pas techniquement écrire statiques les méthodes d'extension, au lieu de ce code exploite une faille dans les méthodes d'extension. Cette échappatoire étant que l'on peut appeler des méthodes d'extension sur des objets nuls sans nulle exception (sauf si vous avez accès à quoi que ce soit via @ce).
Alors, voici comment vous pourriez utiliser ceci:
Maintenant, POURQUOI ai-je choisir d'appeler le constructeur par défaut comme un exemple, ET pourquoi n'ai-je pas juste de retour de new T() dans le premier extrait de code sans avoir à faire tout l'Expression de déchets?
Eh bien aujourd'hui votre jour de chance parce que vous obtenez un 2fer. Comme toute avancée .NET développeur sait, new T() est lent, car il génère un appel Système.Activator qui utilise la réflexion pour obtenir le constructeur par défaut avant de l'appeler. Putain vous Microsoft!
Cependant mon code appelle le constructeur par défaut de l'objet directement.
Statique extensions serait mieux que cela, mais les temps désespérés appellent des mesures désespérées.
XConsole
,ConsoleHelper
et ainsi de suite.(null as DataSet).Create();
pourrait êtredefault(DataSet).Create();
.var someObject = (SomeObject)null;
ouvar someObject = default(SomeObject);
, cependant, dans ce cas c'est vraiment cool que vous pouvez faire:SomeObject SomeObject = SomeObject.Create();
ou si vous voulez être détestéSomeObject SomeObject = SomeObject.Create<SomeObject>();
😉Ce n'est pas possible.
Et oui je pense que MS a fait une erreur ici.
Leur décision ne fait pas de sens et les forces de programmeurs à écrire (comme décrit ci-dessus) inutile classe wrapper.
Ici est un bon exemple: en train de s'étendre statique MS tests Unitaires de la classe Assert: je veux 1 plus méthode Assert
AreEqual(x1,x2)
.La seule façon de le faire est de pointer les différentes classes ou écrire un wrapper autour de 100s de différentes Affirmer méthodes. Pourquoi!?
Si la décision a été prise pour permettre des extensions de cas je ne vois pas de raison logique de ne pas autoriser statique extensions. Les arguments au sujet de sectionnement, les bibliothèques ne se met pas en place une fois que les instances peut être prolongé.
Assert.Throws
pour la réponse, stackoverflow.com/questions/113395/...Je suis tombé sur ce fil, tout en essayant de trouver une réponse à la même question de l'OP eu. Je n'ai pas trouvé la réponse que je voulais, mais j'ai fini par faire cette.
Et je l'utilise comme ceci:
Vous pourriez peut-être ajouter une classe statique avec l'espace de noms personnalisé et le même nom de classe:
Nope. Méthode d'Extension des définitions nécessitent une instance du type que vous êtes l'extension. Son malheureux; je ne sais pas pourquoi sa...
De C#7 ce n'est pas pris en charge. Il y a cependant les discussions sur l'intégration de quelque chose comme ça en C#8 et les propositions qui mérite d'être soutenu.
Comme pour les méthodes d'extension, les méthodes d'extension sont eux-mêmes statique; mais ils sont invoqués comme si ils sont des méthodes d'instance. Depuis une classe statique n'est pas instanciable, vous n'auriez jamais une instance de la classe pour appeler une méthode d'extension de. Pour cette raison, le compilateur ne pas permettre l'extension de définir des méthodes pour les classes statiques.
M. Odieux a écrit: "Comme toute avancée .NET développeur sait, new T() est lent, car il génère un appel Système.Activator qui utilise la réflexion pour obtenir le constructeur par défaut avant d'appeler ça".
New() est compilé à l'IL "newobj" instruction si le type est connu au moment de la compilation. Newobj prend un constructeur pour l'invocation directe. Les appels Système.Activateur.CreateInstance() à compiler le IL "appel" instruction à invoquer Système.Activateur.CreateInstance(). New() lorsqu'il est utilisé contre les types génériques sera la suite d'un appel Système.Activateur.CreateInstance(). Le post de M. Odieux était pas clair sur ce point... et bien, désagréable.
Ce code:
produit ce IL:
Vous ne pouvez pas ajouter de statique méthodes à un type. Vous pouvez uniquement ajouter des (pseudo-)les méthodes d'instance à une instance d'un type.
Le point de la
this
modificateur est-à-dire que le compilateur C# pour passer à l'instance sur le côté gauche de la.
que le premier paramètre de la statique/extension de la méthode.Dans le cas de l'ajout de méthodes statiques à un type, il n'existe aucune instance de passer pour le premier paramètre.
J'ai essayé de le faire avec le Système.L'environnement de l'époque où j'étais à l'apprentissage des méthodes d'extension et n'a pas réussi. La raison en est, comme d'autres, mentionner, car les méthodes d'extension nécessitent une instance de la classe.
oui, dans un sens restreint.
Cela fonctionne, mais la Console n'est pas parce qu'il est statique.
Cela fonctionne parce que tant qu'il n'est pas sur le même espace de noms. Le problème, c'est que vous avez à écrire un proxy statique de la méthode pour chaque méthode de ce Système.Console. Ce n'est pas nécessairement une mauvaise chose que vous pouvez ajouter quelque chose comme ceci:
ou
La façon dont cela fonctionne est que vous vous accrochez à quelque chose dans la norme WriteLine. Il pourrait être un nombre de lignes ou mauvais mot de filtre ou de quoi que ce soit. Chaque fois que vous venez de spécifier Console dans votre espace de noms de dire WebProject1 et importer l'espace de noms du Système, WebProject1.La Console sera choisie au Système.Console en tant que par défaut pour ces classes dans l'espace de noms WebProject1. Donc, ce code va tourner toute la Console.WriteLine appels en bleu dans la mesure où vous n'avez jamais Système spécifié.Console.WriteLine.
Ce qui suit a été rejetée comme une modifier à tvanfosson de réponse. J'ai été invité à participer comme ma propre réponse. J'ai utilisé sa suggestion et a terminé la mise en œuvre d'un
ConfigurationManager
wrapper. En principe, j'ai simplement rempli le...
dans tvanfosson de réponse.Il n'est pas possible d'écrire une extension de la méthode, cependant, il est possible d'imiter le comportement que vous demandez.
Ce qui vous permettra d'appel de la Console.WriteBlueLine(fooText) dans d'autres classes. Si les autres classes qui veulent avoir accès à l'autre statique fonctions de la Console, ils devront être explicitement mentionnés par leurs noms.
Vous pouvez toujours ajouter toutes les méthodes pour le remplacement de la classe, si vous voulez avoir tous en un seul endroit.
De sorte que vous auriez quelque chose comme
Ce serait le genre de comportement que vous recherchez.
*Note de la Console devra être ajoutée au travers de l'espace de noms que vous le mettez dans.
Vous pouvez utiliser un cast sur null pour le faire fonctionner.
L'extension:
YourType:
Vous POUVEZ le faire si vous êtes prêt à "branler" un peu en faisant une variable de la classe statique et de l'affecter à la valeur null. Cependant, cette méthode ne serait pas disponible pour les appels statiques de la classe, donc pas sûr de savoir comment bien l'utiliser serait: