【发布时间】:2009-10-10 16:02:40
【问题描述】:
是否可以使用扩展方法访问对象的私有变量?
【问题讨论】:
标签: c# extension-methods
是否可以使用扩展方法访问对象的私有变量?
【问题讨论】:
标签: c# extension-methods
没有。您可以在扩展方法中执行与在某些实用程序类中的“普通”静态方法中相同的操作。
所以这个扩展方法
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;
}
}
}
你会得到一个编译错误提示
扩展方法必须定义在顶级静态类中; Extensions 是一个嵌套类
请注意,有趣的是,删除 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");
【讨论】:
不,除非您通过公共属性或代理模式授予对它们的某种访问权限。
【讨论】:
如果您拥有要扩展的类,则始终可以声明该类的部分,然后扩展该类并可以访问不同文件中的所有私有成员...但是您实际上不会使用扩展方法.
【讨论】:
扩展方法本质上是一个静态方法,因此您只能访问调用扩展方法的实例的公共成员
【讨论】: