2009-10-10 20 views

Respuesta

67

No. Puede hacer lo mismo en un método de extensión que en un método estático "normal" en alguna clase de utilidad.

Así que esta extensión método

public static void SomeMethod(this string s) 
{ 
    // do something with 's' 
} 

es equivalente a algún método de ayuda estático como sigue (al menos en cuanto a lo que puede acceder):

public static void SomeStringMethod(string s) 
{ 
    // do something with 's' 
} 

(Por supuesto que podría utilizar un poco de reflexión en el cualquiera de los métodos para acceder a miembros privados. Pero supongo que ese no es el punto de esta pregunta.)

+1

+1. Como un aparte, puede tener métodos de extensión privados; hay un buen artículo sobre esto en http://odetocode.com/Blogs/scott/archive/2009/10/05/private-extension-methods.aspx. Los métodos de extensión también pueden acceder a miembros privados estáticos de su clase de utilidad estática. – TrueWill

+3

Aunque está etiquetado como C#, esto se aplica a cualquiera de los lenguajes .NET que brindan soporte para los métodos de extensión. –

+0

@TrueWill - pero dado que deben ser tipos estáticos, no anidados y no genéricos, no pueden tener acceso privado a las variables * de ningún objeto *. acceso 'interno', seguro, pero no 'privado'. –

3

No, a menos que les dé algún tipo de acceso a ellos a través de public pro erties o un patrón de proxy.

11

No:

public class Foo 
{ 
    private string bar; 
} 

public static class FooExtensions 
{ 
    public static void Test(this Foo foo) 
    { 
     // Compile error here: Foo.bar is inaccessible due to its protection level 
     var bar = foo.bar; 
    } 
} 
0

un método de extensión es esencialmente un método estático por lo que lo único que tiene acceso a son los miembros públicos de la instancia en la que se invoca el método de extensión en

15

No, no puede.

Sin embargo, le interesará saber que las otras respuestas son incorrectas al decir que los métodos estáticos normales no pueden acceder a los campos privados. Un método estático puede acceder a campos de miembros privados no estáticos en su propia clase. El siguiente código es perfectamente válido y muestra un método estático para acceder a un campo privado:

public class Foo 
{ 
    private bool _field; 

    public static bool GetField(Foo foo) 
    { 
     return foo._field; 
    } 
} 

Ahora ... volver a su pregunta. Se podría pensar que un método de extensión debería ser capaz de hacer lo mismo, dada la "equivalencia" (inexistente) con los métodos estáticos que existen otras respuestas. Sin embargo, no puede declarar métodos de extensión dentro de una clase anidada. Así que si usted trata de hacer lo siguiente:

public class Foo 
{ 
    private bool _field; 

    public static class Extensions 
    { 
     public static bool GetField(this Foo foo) 
     { 
      return foo._field; 
     } 
    } 
} 

Cuando conteste diciendo un error de compilación

método de extensión debe ser definido en una clase estática nivel superior; Extensiones es una clase anidada

Tenga en cuenta que, curiosamente, eliminar la palabra clave this hace que el código compile bien. Las razones de esto se discuten aquí:

  1. Why are extension methods only allowed in non-nested, non-generic static class?
  2. Why not allow Extension method definition in nested class?
+1

excelencia en ingeniería. – Fattie

1

Si usted es dueño de la clase que se está extendiendo, que una siempre declaran la clase parcial, a continuación, extender la clase & tienen acceso a todos los miembros privados en un archivo diferente ... Pero realmente no estarías usando métodos de extensión.

0

utilizar la reflexión

no se recomienda, pero lo que pueda acceder a cualquier variable privada de cualquier tipo utilizando otro método de extensión de este modo:

public static T GetFieldValue<T>(this object obj, string name) { 
    var field = obj.GetType().GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 
    return (T)field?.GetValue(obj); 
} 

y luego acceder a un campo privado de un tipo arbitrario:

Foo foo = new Foo(); 
string privateBar = foo.GetFieldValue<string>("_bar"); 
Cuestiones relacionadas