web-dev-qa-db-fra.com

Comment puis-je étendre une classe avec des méthodes d'extension c #?

Les méthodes d'extension peuvent-elles être appliquées à la classe?

Par exemple, étendez DateTime pour inclure une méthode Tomorrow () pouvant être appelée, par exemple:

DateTime.Tomorrow();

Je sais que je peux utiliser 

static DateTime Tomorrow(this Datetime value) { //... }

Ou

public static MyClass {
  public static Tomorrow() { //... }
}

pour un résultat similaire, mais comment puis-je étendre DateTime pour pouvoir appeler DateTime.Tomorrow?

90
David Glenn

Vous ne pouvez pas ajouter de méthodes à un type existant à moins que le type existant soit marqué comme partiel, vous pouvez uniquement ajouter des méthodes qui apparaissent pour être membre du type existant via des méthodes d'extension. Etant donné que c'est le cas, vous ne pouvez pas ajouter de méthodes statiques au type lui-même car les méthodes d'extension utilisent des instances de ce type.

Rien ne vous empêche de créer votre propre méthode d'assistance statique comme celle-ci:

static class DateTimeHelper
{
    public static DateTime Tomorrow
    {
        get { return DateTime.Now.AddDays(1); }
    }
}

Ce que vous utiliseriez comme ceci:

DateTime tomorrow = DateTimeHelper.Tomorrow;
67
Andrew Hare

Utilisez une méthode extension .

Ex:

namespace ExtensionMethods
{
    public static class MyExtensionMethods
    {
        public static DateTime Tomorrow(this DateTime date)
        {
            return date.AddDays(1);
        }    
    }
}

Usage:

DateTime.Now.Tomorrow();

ou

AnyObjectOfTypeDateTime.Tomorrow();
170
Kumu

Les méthodes d'extension sont un sucre syntaxique permettant de créer des méthodes statiques dont le premier paramètre est une instance de type T, comme si elles étaient une méthode d'instance sur T.

En tant que tel, l’avantage est en grande partie perdu lorsque vous créez des «méthodes d’extension statique», car elles dérangeraient encore plus le lecteur du code qu’une méthode d’extension (car elles semblent pleinement qualifiées mais ne sont pas définies dans cette classe). sans gain syntaxique (pouvoir enchaîner les appels dans un style fluide au sein de Linq par exemple).

Etant donné que vous devez de toute façon rendre les extensions possibles avec une utilisation, je dirais qu'il est plus simple et plus sûr de créer: 

public static class DateTimeUtils
{
    public static DateTime Tomorrow { get { ... } }
}

Et utilisez ensuite ceci dans votre code via:

WriteLine("{0}", DateTimeUtils.Tomorrow)
17
ShuggyCoUk

Le plus proche de ma réponse est d'ajouter une méthode d'extension dans un objet System.Type. Pas joli, mais toujours intéressant.

public static class Foo
{
    public static void Bar()
    {
        var now = DateTime.Now;
        var tomorrow = typeof(DateTime).Tomorrow();
    }

    public static DateTime Tomorrow(this System.Type type)
    {
        if (type == typeof(DateTime)) {
            return DateTime.Now.AddDays(1);
        } else {
            throw new InvalidOperationException();
        }
    }
}

Sinon, IMO Andrew et ShuggyCoUk ont ​​une meilleure mise en œuvre.

9
Adrian Godong

Ils offrent la possibilité d'étendre les types existants en ajoutant de nouvelles méthodes sans aucune modification nécessaire. L’appel de méthodes à partir d’objets du type étendu au sein d’une application à l’aide de la syntaxe de méthode d’instance est appelé méthode ‘‘ ‘’ ’’ étendre ’’. Les méthodes d'extension ne sont pas des membres d'instance du type . Le point essentiel à retenir est que les méthodes d'extension, définies en tant que méthodes statiques, ne sont dans la portée que lorsque l'espace de nom est explicitement importé dans le code source de votre application via la directive using. Même si les méthodes d'extension sont définies comme des méthodes statiques, elles sont toujours appelées à l'aide de la syntaxe d'instance.

Consultez l'exemple complet ici http://www.dotnetreaders.com/articles/Extension_methods_in_C-sharp.net,Methods_in_C_-sharp/201

Exemple:

class Extension
    {
        static void Main(string[] args)
        {
            string s = "sudhakar";
            Console.WriteLine(s.GetWordCount());
            Console.ReadLine();
        }

    }
    public static class MyMathExtension
    {

        public static int GetWordCount(this System.String mystring)
        {
            return mystring.Length;
        }
    }
3
sudhakar

Je ferais la même chose que Kumu

namespace ExtensionMethods
{
    public static class MyExtensionMethods
    {
        public static DateTime Tomorrow(this DateTime date)
        {
           return date.AddDays(1);
        }    
    }
}

mais appelez-le comme ce nouveau DateTime (). Tomorrow ();

Je pense que cela fait plus de seens que DateTime.Now.Tomorrow ();

3
mimo

Je cherchais quelque chose de similaire - une liste de contraintes sur les classes fournissant des méthodes d'extension. Il semble difficile de trouver une liste concise, alors voici:

  1. Vous ne pouvez avoir aucun contenu privé ou protégé - champs, méthodes, etc.

  2. Ce doit être une classe statique, comme dans public static class....

  3. Seules les méthodes peuvent être dans la classe et elles doivent toutes être publiques statiques.

  4. Vous ne pouvez pas avoir de méthodes statiques conventionnelles - celles qui n'incluent pas cet argument ne sont pas autorisées.

  5. Toutes les méthodes doivent commencer:

    public statique ReturnType MethodName (this ClassName _this, ...)

Donc, le premier argument est toujours la référence this.

Cela crée un problème implicite: si vous ajoutez des méthodes qui nécessitent un verrou, vous ne pouvez pas le fournir au niveau de la classe. Généralement, vous fournissez un verrou privé au niveau de l'instance, mais il n'est pas possible d'ajouter de champs privés, ce qui vous laisse avec des options très gênantes, telles que le fournir en tant que statique publique sur certaines classes externes, etc. Signes le langage C # avait en quelque sorte un mauvais tournant dans la conception de ces .

La solution consiste à utiliser votre classe de méthode d'extension comme une simple façade à une classe normale. Toutes les méthodes statiques de votre classe d'extension appellent simplement la classe réelle, probablement à l'aide de a Singleton .

3
Chris Moschini

Malheureusement, vous ne pouvez pas faire ça. Je crois que ce serait utile, cependant. Il est plus naturel de taper:

DateTime.Tomorrow

que:

DateTimeUtil.Tomorrow

Avec une classe Util, vous devez vérifier l'existence d'une méthode statique dans deux classes différentes, au lieu d'une. 

2
Meta-Knight

Nous avons amélioré notre réponse avec l'explication détaillée.Maintenant, il est plus facile de comprendre la méthode d'extension

Méthode d'extension : Il s'agit d'un mécanisme grâce auquel nous pouvons étendre le comportement d'une classe existante sans utiliser la sous-classification ni modifier ou recompiler la classe ou la structure d'origine. 

Nous pouvons étendre nos classes personnalisées, classes de framework .net, etc.

La méthode d'extension est en fait un type spécial de méthode statique définie dans la classe statique.

Comme la classe DateTime est déjà prise ci-dessus, nous n'avons donc pas pris cette classe pour l'explication.

Ci-dessous l'exemple

// Ceci est une classe existante de calculatrice qui ont une seule méthode (Ajouter)

public class Calculator 
{
    public double Add(double num1, double num2)
    {
        return num1 + num2;
    }

}

// Below is the extension class which have one extension method.  
public static class Extension
{
    // It is extension method and it's first parameter is a calculator class.It's behavior is going to extend. 
    public static double Division(this Calculator cal, double num1,double num2){
       return num1 / num2;
    }   
}

// We have tested the extension method below.        
class Program
{
    static void Main(string[] args)
    {
        Calculator cal = new Calculator();
        double add=cal.Add(10, 10);
        // It is a extension method in Calculator class.
        double add=cal.Division(100, 10)

    }
}
0
Sheo Dayal Singh