Can C# extension methods access private variables?

前端 未结 7 1014
借酒劲吻你
借酒劲吻你 2021-02-01 11:49

Is it possible to access an object\'s private variables using an extension method?

相关标签:
7条回答
  • 2021-02-01 12:14

    No it cannot.

    However, you will be interested to know that the other answers are incorrect in saying that normal static methods cannot access private fields. A static method can access private non-static member fields in its own class. The following code is perfectly valid and shows a static method accessing a private field:

    public class Foo
    {
        private bool _field;
    
        public static bool GetField(Foo foo)
        {
            return foo._field;
        }
    }
    

    Now... back to your question. You might think that an extension method should be able to do the same thing, given the (non-existent) "equivalence" to static methods that other answers claim exists. However, you cannot declare extension methods inside a nested class. So if you try to do the following:

    public class Foo
    {
        private bool _field;
    
        public static class Extensions
        {
            public static bool GetField(this Foo foo)
            {
                return foo._field;
            }
        }
    }
    

    You will get a compile error saying

    Extension method must be defined in a top level static class; Extensions is a nested class

    Note that, interestingly enough, removing the this keyword causes the code to compile fine. The reasons for this are discussed here:

    1. Why are extension methods only allowed in non-nested, non-generic static class?
    2. Why not allow Extension method definition in nested class?
    0 讨论(0)
  • 2021-02-01 12:18

    Use Reflection

    Not recommended, but you could possibly access any private variable of any type using another extension method like so:

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

    And then access a private field of an arbitrary type:

    Foo foo = new Foo();
    string privateBar = foo.GetFieldValue<string>("_bar");
    
    0 讨论(0)
  • 2021-02-01 12:21

    No:

    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;
        }
    }
    
    0 讨论(0)
  • 2021-02-01 12:24

    An extension method is essentially a static method so all you have access to are the public members of the instance on which the extension method is invoked on

    0 讨论(0)
  • 2021-02-01 12:27

    No, unless you give some kind of access to them through public properties or a proxy pattern.

    0 讨论(0)
  • 2021-02-01 12:36

    No. You can do the same in an extension method as in a "normal" static method in some utility class.

    So this extension method

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

    is equivalent to some static helper method like this (at least regarding what you can access):

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

    (Of course you could use some reflection in either method to access private members. But I guess that's not the point of this question.)

    0 讨论(0)
提交回复
热议问题