2009-10-10 14 views

Odpowiedz

67

Nie. Możesz zrobić to samo w metodzie rozszerzenia, jak w "normalnej" metodzie statycznej w niektórych klasach narzędzi.

Więc to rozszerzenie metoda

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

jest równoznaczne z pewnym statycznej metody pomocnika tak (przynajmniej jeśli chodzi o to, co można uzyskać dostęp):

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

(Oczywiście można korzystać z niektórych odbicie w albo metodę uzyskiwania dostępu do prywatnych użytkowników, ale myślę, że nie o to pytam.)

+1

+1. Na marginesie możesz mieć prywatne metody przedłużania; istnieje dobry artykuł na ten temat na http://odetocode.com/Blogs/scott/archive/2009/10/05/private-extension-methods.aspx Metody rozszerzeń mogą również uzyskać dostęp do prywatnych statycznych członków ich statycznej klasy narzędziowej. – TrueWill

+3

Mimo że jest to oznaczane jako C#, dotyczy to dowolnego z języków .NET, które zapewniają obsługę metod rozszerzeń. –

+0

@TrueWill - ale ponieważ muszą być typami statycznymi, nie-zagnieżdżonymi, nietypowymi, nie mogą tak naprawdę mieć prywatnego dostępu do żadnych * zmiennych * obiektu. "wewnętrzny" dostęp, na pewno - ale nie "prywatny". –

3

Nie, chyba że dasz jakiś dostęp do nich poprzez publiczne wsparcie właściwości lub wzorzec proxy.

11

nr:

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

metodę rozszerzenia jest przede wszystkim metoda statyczna więc wszystko masz dostęp do są publiczne członkowie przykład, w którym metoda rozszerzenie jest wywoływany na

15

Nie, nie mogę.

Będziesz jednak chciał wiedzieć, że inne odpowiedzi są nieprawidłowe, mówiąc, że normalne metody statyczne nie mogą uzyskać dostępu do prywatnych pól. Metoda statyczna może uzyskać dostęp do prywatnych niestatycznych pól elementów w swojej własnej klasie. Poniższy kod jest całkowicie poprawny i pokazuje metody statycznej dostępem prywatną murawę:

public class Foo 
{ 
    private bool _field; 

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

... Teraz z powrotem do Twojego pytania. Możesz myśleć, że metoda rozszerzenia powinna być w stanie zrobić to samo, biorąc pod uwagę (nieistniejącą) "równoważność" ze statycznymi metodami, które istnieją w innych odpowiedziach. Jednak nie można zadeklarować metod rozszerzenia w klasie zagnieżdżonej. Więc jeśli spróbować wykonać następujące czynności:

public class Foo 
{ 
    private bool _field; 

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

dostaniesz błąd kompilacji mówiąc

metoda Rozszerzenie musi być zdefiniowana w klasie statycznej najwyższego poziomu; Rozszerzenia są zagnieżdżonymi klasami:

Uwaga: co ciekawe, usunięcie słowa kluczowego this powoduje, że kod jest kompilowany poprawnie. Przyczyny tego są omówione tutaj:

  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

doskonałość w inżynierii. – Fattie

1

Jeśli jesteś właścicielem klasy, które są rozciągające, ci zawsze zadeklarować klasę częściową, a następnie rozszerzyć klasę & mieć dostęp do wszystkich prywatnych członków w innym pliku ... Ale tak naprawdę nie używasz metod rozszerzenia.

0

użyć refleksji

Nie zalecany, ale można ewentualnie uzyskać dostęp do dowolnej zmiennej prywatnej dowolnego typu za pomocą innej metody rozszerzenie tak:

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); 
} 

A następnie uzyskać dostęp do prywatnych pola z dowolnego typu:

Foo foo = new Foo(); 
string privateBar = foo.GetFieldValue<string>("_bar"); 
Powiązane problemy