2009-11-02 3 views
4

J'ai vu cela dans une réponse par Marc Gravell, et je ne vois pas comment cela fonctionneraitComment ce travail (extension statique?)

static bool IsNullOrEmpty(this string value) 
{  
    return string.IsNullOrEmpty(value); 
} 

Si pas un appel à s.IsNullOrEmpty () où s est null, puis retourne une exception NullReferenceException? Comment pouvez-vous dé-référencer l'objet pour appeler la fonction définie ici si l'objet est null?

Ou est-ce un moyen de contourner un singe en corrigeant une fonction statique?

Répondre

12

Les méthodes d'extension sont magiques - ils ne regardent comme les méthodes d'instance, mais étant donné la méthode d'extension:

public static class StaticClass { 
    public static void MyMethod(this SomeType obj) // note "this" 
    {...} 
} 

alors:

instance.MyMethod(); 

compile à:

StaticClass.MyMethod(instance); 

Et vous ne vous attendez pas à ce que vous jetiez un NullReferenceException - et en effet ce n'est pas le cas.

Ceci est à double tranchant. À certains niveaux, c'est déroutant, mais cela peut être très utile. Il serait bon d'ajouter votre propre vérification null-ref au début, sauf si vous avez une raison pour autoriser les valeurs nulles. Un autre utile:

public static void ThrowIfNull<T>(T value, string name) where T : class { 
    if(value==null) throw new ArgumentNullException(name); 
} 
... 
void SomeUnrelatedMethod(string arg) { 
    arg.ThrowIfNull("arg"); 
} 
+0

Vous voulez probablement dire "méthodes d'extension" au lieu de "méthodes statiques" dans la première phrase ... –

+0

d'oh! Effectivement. Clarifié. Gros oops pour moi. –

2

Les méthodes d'extension peut être appelée sur les valeurs nulles. Un appel comme ceci:

bool x = foo.IsNullOrEmpty(); 

est simplement traduit à la compilation en

bool x = ExtensionClass.IsNullOrEmpty(foo); 

Aucune vérification de nullité est effectuée implicitement. C'est du sucre syntaxique très simple, fondamentalement.

Bien que ce soit étrange quand vous le voyez pour la première fois, c'est très pratique pour des tests exactement comme ça. Je également une méthode d'extension I Comme pour la validation des paramètres:

x.ThrowIfNull(); 

qui jette ArgumentNullException si x est nulle.

+0

Les méthodes d'extension ne peuvent être appelées que sur des valeurs nulles s'il n'est pas évident pour le compilateur qu'elles sont nulles. AFAIK, '((chaîne) null) .Extension()' ne compilerait pas, donc pas 'default (chaîne) .Extension()'. –

+1

@Stefan: Je viens de l'essayer, et les deux compilent. Ce dernier émet un avertissement trompeur (ce qui est regrettable) mais le premier compile sans aucun problème. –

Questions connexes