2009-10-10 63 views

回答

67

不。您可以在擴展方法中執行與某些實用程序類中的「正常」靜態方法相同的操作。

所以這個擴展方法

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

相當於一些像這樣的靜態輔助方法(至少就可以訪問什麼):

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

(當然你可以在使用一些反思但我想這不是這個問題的要點)

+1

+1。順便說一句,你可以有私人擴展方法;這裏有一篇很好的文章http://odetocode.com/Blogs/scott/archive/2009/10/05/private-extension-methods.aspx擴展方法也可以訪問其靜態實用程序類的私有靜態成員。 – TrueWill 2009-10-10 16:49:12

+3

儘管這被標記爲C#,但這適用於爲擴展方法提供支持的任何.NET語言。 – 2009-10-10 17:25:37

+0

@TrueWill - 但由於它們必須是靜態的,非嵌套的非泛型類型,它們不能真正擁有對任何*對象的*變量的私有訪問權限。 「內部」訪問,當然 - 但不是「私人」。 – 2009-10-10 22:31:18

3

不,除非你通過公共道具給他們某種形式的訪問erties或代理模式。

11

號:

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

擴展方法本質上是一種靜態方法,因此所有可以訪問的實例的公衆成員在其上

15

不,它不能被調用的擴展方法。

但是,您將有興趣知道其他答案在說正常的靜態方法無法訪問專用字段時不正確。 靜態方法可以訪問其自己的類中的私有非靜態成員字段。下面的代碼是完全有效的,並顯示一個靜態方法訪問私有字段:

public class Foo 
{ 
    private bool _field; 

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

現在......回到你的問題。考慮到其他答案聲稱存在的(不存在的)「靜態方法」的「等價性」,您可能會認爲擴展方法應該能夠做同樣的事情。但是,您不能在嵌套類中聲明擴展方法。所以,如果你嘗試做到以下幾點:

public class Foo 
{ 
    private bool _field; 

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

你會得到一個編譯錯誤說

擴展方法必須在頂級靜態類中定義;擴展是嵌套類

請注意,有趣的是,刪除this關鍵字會導致代碼編譯正常。造成這種情況的原因是這裏討論:

  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

卓越的工程。 – Fattie 2016-03-26 15:55:48

1

如果你擁有的是要擴展的類,您可以隨時類聲明部分,然後擴展類&訪問給不同文件中的所有私人成員......但是你不會真的在使用擴展方法。

0

使用反射

不推薦,但你可以使用像其他擴展方法,從而可能訪問任何類型的任何私有變量:

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

然後訪問任意類型的私有字段:

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