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

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

66 голосов | спросил Geo 10 +04002009-10-10T20:02:40+04:00312009bEurope/MoscowSat, 10 Oct 2009 20:02:40 +0400 2009, 20:02:40

7 ответов


0

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

Так что этот метод расширения

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

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

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

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

ответил M4N 10 +04002009-10-10T20:05:47+04:00312009bEurope/MoscowSat, 10 Oct 2009 20:05:47 +0400 2009, 20:05:47
0

Нет, не может.

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

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. Почему бы не разрешить определение метода расширения в вложенный класс?
ответил Zaid Masud 20 PM00000020000000731 2012, 14:30:07
0
Нет:
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;
    }
}
ответил Darin Dimitrov 10 +04002009-10-10T20:06:12+04:00312009bEurope/MoscowSat, 10 Oct 2009 20:06:12 +0400 2009, 20:06:12
0

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

ответил Yuriy Faktorovich 10 +04002009-10-10T20:05:55+04:00312009bEurope/MoscowSat, 10 Oct 2009 20:05:55 +0400 2009, 20:05:55
0

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

ответил Rimbimbambo 10 AM00000040000005331 2013, 04:18:53
0

Использовать отражение

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

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");
ответил Bruno Zell 29 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 29 Sep 2017 15:30:54 +0300 2017, 15:30:54
0

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

ответил Abhijeet Patel 10 +04002009-10-10T21:09:03+04:00312009bEurope/MoscowSat, 10 Oct 2009 21:09:03 +0400 2009, 21:09:03

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132