是否可以使用扩展方法访问对象的私有变量?
Answers:
不可以。在扩展方法中,您可以像在某些实用工具类中的“常规”静态方法中一样进行操作。
所以这个扩展方法
public static void SomeMethod(this string s)
{
// do something with 's'
}
等效于这样的静态辅助方法(至少关于您可以访问的内容):
public static void SomeStringMethod(string s)
{
// do something with 's'
}
(当然,您可以在这两种方法中使用一些反射来访问私有成员。但是我想这不是这个问题的重点。)
internal
访问,当然-但不是private
。
不,它不能。
但是,您将有兴趣知道其他答案是不正确的,因为它们说普通的静态方法无法访问私有字段。静态方法可以访问其自己类中的私有非静态成员字段。以下代码完全有效,并显示了访问私有字段的静态方法:
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
关键字会使代码正确编译。原因在这里讨论:
没有:
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 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");
不可以,除非您通过公共属性或代理模式对它们进行某种访问。
扩展方法本质上是静态方法,因此您可以访问的所有实例都是在其上调用扩展方法的实例的公共成员。