Могут ли методы расширения С# получить доступ к закрытым переменным?

Можно ли получить доступ к закрытым переменным объекта с помощью метода расширения?

Ответ 1

Нет. Вы можете сделать то же самое в методе расширения, что и в "обычном" статическом методе в некотором классе утилиты.

Итак, этот метод расширения

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

эквивалентен некоторому статическому вспомогательному методу, подобному этому (по крайней мере, относительно того, что вы можете получить):

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

(Конечно, вы могли бы использовать некоторое отражение в любом методе для доступа к частным членам. Но я думаю, что это не вопрос этого вопроса.)

Ответ 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 приводит к компиляции кода. Причины этого обсуждаются здесь:

Ответ 3

<Не p > Нет:
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;
    }
}

Ответ 4

Нет, если вы не предоставили какой-либо доступ к ним через общедоступные свойства или шаблон прокси.

Ответ 5

Если вы владеете классом, который вы расширяете, вы всегда объявляете частичный класс, затем расширяете класс и получаете доступ ко всем частным членам в другом файле... Но вы действительно не использовали бы методы расширения.

Ответ 6

Метод расширения по существу является статическим методом, поэтому все, к чему у вас есть доступ, являются публичными членами экземпляра, на который вызывается метод расширения на

Ответ 7

Не рекомендуется, но вы можете получить доступ к любой частной переменной любого типа, используя другой метод расширения, например:

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