是否可以使用扩展方法访问对象的私有变量?
答案 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
关键字会导致代码编译正常。这里讨论的原因如下:
答案 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)
扩展方法本质上是一个静态方法,因此您可以访问的是在其上调用扩展方法的实例的公共成员