101 votes

"this" dans le paramètre de la fonction

En regardant quelques exemples de code pour HtmlHelpers, et je vois des déclarations qui ressemblent à :

public static string HelperName(this HtmlHelper htmlHelper, ...more regular params )

Je ne me souviens pas d'avoir vu ce type de construction ailleurs - quelqu'un peut-il expliquer le but du "this" ? Je pensais qu'en déclarant quelque chose de public static, cela signifiait que la classe n'avait pas besoin d'être instanciée - alors à quoi sert "this" dans ce cas ?

239voto

Lasse V. Karlsen Points 148037

Il s'agit de la syntaxe de déclaration des méthodes d'extension, une nouvelle fonctionnalité de C# 3.0.

Une méthode d'extension est une partie du code, une partie de la "magie" du compilateur, où le compilateur, avec l'aide de l'intellisense dans Visual Studio, fait apparaître que votre méthode d'extension est en fait disponible comme une méthode d'instance sur l'objet en question.

Laissez-moi vous donner un exemple.

Aucune méthode de la classe String ne porte le nom de GobbleGobble, alors créons une méthode d'extension :

public static class StringExtensions
{
    public static void GobbleGobble(this string s)
    {
        Console.Out.WriteLine("Gobble Gobble, " + s);
    }
}

Le nom de la classe est juste ma convention de dénomination, il n'est pas nécessaire de la nommer ainsi, mais elle doit être statique, tout comme la méthode.

Après avoir déclaré la méthode ci-dessus, vous pouvez, dans Visual Studio, taper ceci :

String s = "Turkey Baster!";
s.

après le point, attendez l'intellisense, et remarquez qu'il y a une méthode GobbleGobble, complétez le code comme ceci :

String s = "Turkey Baster!";
s.GobbleGobble();

Important : La classe où est déclarée la méthode d'extension doit être disponible pour le compilateur et le processeur intellisense afin qu'intellisense affiche la méthode. Si vous tapez GobbleGobble manuellement, et que vous utilisez la fonction Ctrl + . mais il ne vous aidera pas à introduire les bonnes directives d'utilisation dans le fichier.

Remarquez que le paramètre de la méthode a disparu. Le compilateur va déplacer silencieusement les bits importants, qui sont :

String s = "Turkey Baster!";
s.GobbleGobble();
^     ^
|     +-- the compiler will find this in the StringExtensions class
|
+-- will be used as the first parameter to the method

Ainsi, le code ci-dessus sera transformé par le compilateur en ceci :

String s = "Turkey Baster!";
StringExtensions.GobbleGobble(s);

Ainsi, au moment de l'appel, il n'y a rien de magique, il s'agit simplement d'un appel à une méthode statique.

Notez que si votre méthode d'extension déclare plus d'un paramètre, seul le premier prend en charge la méthode d'extension. this et le reste doit être spécifié dans le cadre de l'appel de la méthode, comme d'habitude :

public static void GobbleGobble(this string value, string extra)
{                                            |              |
    ...                                      |              |
}                                            |              |
                                             |              |
+--------------------------------------------+              |
|                                                           |
v                                                           |
s.GobbleGobble("extra goes here");                          |
                        ^                                   |
                        |                                   |
                        +-----------------------------------+

Les méthodes d'extension ont été ajoutées en partie grâce à Linq, où la syntaxe Linq de C# recherche des méthodes d'extension nommées de manière appropriée pour les objets en jeu, ce qui signifie que vous pouvez "introduire" le support Linq dans n'importe quel type de classe en déclarant simplement les bonnes méthodes d'extension. Bien sûr, le support complet de Linq représente beaucoup de travail, mais c'est possible.

De plus, les méthodes d'extension en elles-mêmes sont vraiment utiles, alors lisez-les.

Voici quelques liens :

9voto

csharpdev Points 806

Après les méthodes d'extension, je les utilise comme un fou en voici quelques-unes que j'utilise constamment

public static T ChangeType<T>(this object obj)
{
  return (T)Convert.ChangeType(obj, typeof(T));
}

Ça marche comme ça

int i = "123".ChangeType<int>();
bool valid = "bool".ChangeType<bool>();
int id = dataSet.Tables[0].Rows[0]["Id"].ChangeType<int>();

Oui, il apparaît sur chaque objet, ce qui peut être ennuyeux, mais comme je l'utilise pour pratiquement tous les types de données, il est plus facile de l'attacher à un objet plutôt que de le dupliquer pour tous les types de données possibles.

public static string ToXml(this object serializableObject)
{
    var aMemStr = new MemoryStream();
    try
    {
        var serializer = new XmlSerializer(serializableObject.GetType());
        serializer.Serialize(new XmlTextWriter(aMemStr, null), serializableObject);
        return Encoding.UTF8.GetString(aMemStr.ToArray());
    }
    finally { if (aMemStr != null) { aMemStr.Dispose(); } }
}

string xml = dataSet.ToXml();

public static T ToObject<T>(this string xmlString)
{
    var aStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString));
    try { return (T)new XmlSerializer(typeof(T)).Deserialize(aStream); }
    finally { if (aStream != null) { aStream.Dispose(); aStream = null; } }
}

DataSet dataSet = xml.ToObject<DataSet>();

6voto

Henrik Jepsen Points 1095

Il est utilisé pour les méthodes d'extension. Fondamentalement, vous "collez" le nom de l'Helper à l'objet htmlHelper de sorte que vous pouvez dire :

new HtmlHelper().HelperName(...more regular params);

6voto

Justin Niessner Points 144953

Ce serait une méthode d'extension. Elles vous permettent d'"étendre" une classe via des méthodes statiques qui se trouvent en dehors de la classe d'origine.

Par exemple, disons que vous avez une méthode de chaîne utile que vous utilisez tout le temps...

public int CountAllAs(string orig)
{
    return orig.ToLowerInvariant().ToArray().Count(c => c == 'a');
}

Et vous l'appelez...

string allAs = "aaaA";
int count = CountAllAs(allAs);

Ce n'est pas trop mal. Mais avec un petit changement, vous pourriez en faire une méthode d'extension et l'appel serait un peu plus joli :

public static int CountAllAs(this string orig)
{
    return orig.ToLowerInvariant().ToArray().Count(c => c == 'a');
}

Et ensuite l'appeler...

string allAs = "aaaA";
int count = allAs.CountAllAs();

4voto

Fraga Points 435

Méthodes d'extension ...

...sont un moyen fantastique d'inclure une fonctionnalité comme si vous utilisiez le motif décoratif mais sans avoir à remanier tout votre code ou à utiliser un nom différent pour un type commun.

public static class Extensions
{
     public static string RemoveComma(this string value)
     {
         if (value == null) throw new ArgumentNullException("value");
        return value.Replace(",", "");
    }
}  

Donc vous pouvez utiliser ce code, n'importe où dans votre application.

Console.WriteLine(“Hello, My, Friend”.RemoveComma())

>> Hello My Friend

Ainsi, le este L'attribut command signifie le type que l'extension sera "ajoutée", et vous permet de travailler avec la valeur comme si elle était passée en paramètre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X