C#扩展方法可以访问私有变量?(Can C# extension methods access pr

2019-08-17 17:02发布

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

Answer 1:

号你可以在一个扩展方法相同,在一些实用工具类“正常”的静态方法。

所以这个扩展方法

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

相当于一些像这样的静态辅助方法(至少就可以访问什么):

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

(当然,你可以使用一些反映在任一方法来访问私有成员。但我想这不是这个问题的地步。)



Answer 2:

不,它不能。

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

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. 为什么不允许在嵌套类的扩展方法定义是什么?


Answer 3:

没有:

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


Answer 4:

不,除非你通过公共属性或代理模式给予某种形式的访问它们。



Answer 5:

如果你拥有的是要扩展的类,您可以随时类声明部分,然后扩展类和访问在不同的文件中的所有私有成员......但你不会真的是使用扩展方法。



Answer 6:

使用反射

不推荐,但你可以使用其他扩展方法,像这样有可能访问任何类型的任何私有变量:

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


Answer 7:

扩展方法本质上是一种静态的方法,所以你可以访问是在其上扩展方法被调用的实例的公共成员



文章来源: Can C# extension methods access private variables?