C#扩展方法可以访问私有变量吗?

时间:2009-10-10 16:02:41

标签: c# extension-methods

是否可以使用扩展方法访问对象的私有变量?

7 个答案:

答案 0 :(得分:71)

没有。您可以在扩展方法中执行相同的操作,就像在某个实用程序类中的“普通”静态方法一样。

所以这个扩展方法

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

等同于这样的一些静态辅助方法(至少关于你可以访问的内容):

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

(当然你可以在任一种方法中使用一些反射来访问私人成员。但我想这不是这个问题的重点。)

答案 1 :(得分:22)

不,不能。

但是,您会有兴趣知道其他答案不正确,说正常的静态方法无法访问私有字段。 静态方法可以访问自己类中的私有非静态成员字段。以下代码完全有效,并显示访问私有字段的静态方法:

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?

答案 2 :(得分: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;
    }
}

答案 3 :(得分:3)

不,除非您通过公共属性或代理模式提供某种访问权限。

答案 4 :(得分:2)

如果您拥有要扩展的类,则始终将该类声明为partial,然后扩展该类&可以访问不同文件中的所有私有成员......但你真的不会使用扩展方法。

答案 5 :(得分:2)

使用反射

不推荐,但您可以使用其他扩展方法访问任何类型的任何私有变量,如下所示:

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

答案 6 :(得分:0)

扩展方法本质上是一个静态方法,因此您可以访问的是在其上调用扩展方法的实例的公共成员