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

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

36520 次浏览

不。您可以在扩展方法中执行与在某些实用程序类中的“普通”静态方法中相同的操作。

所以这个扩展方法

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

相当于这样的一些静态助手方法(至少关于您可以访问的内容) :

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

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

没有,除非你通过公共财产或者代理模式给予他们某种访问权限。

答案是否定的:

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

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

不,它不能。

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

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. 为什么只允许在非嵌套、非泛型静态类中使用扩展方法?
  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");