как работает магия статического видения внутри класса? - PullRequest
1 голос
/ 27 февраля 2012
public class Outer
{
    public  class Inner
    {
        public static string OtherValue { get { return SomeValue; } }
    }

    public static string SomeValue { get { return "Outer"; } }
}

Почему вышеперечисленное компилируется?Разве SomeValue не выходит за рамки Inner и нуждается в квалификации с Outer.SomeValue?Разве вышеупомянутое по сути не совпадает с приведенным ниже (которое не скомпилируется)?

public class Outer
{
    public class Inner
    {
        public static string OtherValue { get { return Outer.SomeValue; } }
    }

    public static string SomeValue { get { return "Outer"; } }
}

Какая магия static происходит здесь?

Ответы [ 4 ]

7 голосов
/ 27 февраля 2012

Это как:

public class Super
{
    public class Sub
    {
        public static string OtherValue { get { return Super.SomeValue; } }
    }

    public static string SomeValue { get { return "Outer"; } }
}

С Super, удерживающим статический SomeValue

<ч /> Это более четко отображается как:

public class Super
{
    public static string SomeValue { get { return "Outer"; } }
}

public class Sub
{
    public static string OtherValue { get { return Super.SomeValue; } }
}

Теперь, когда Sub и Super равны public, их статические свойства видны всем в их общей области видимости. И, как указывает @jonskeet, компилятор будет искать наилучшее соответствие для SomeValue, сначала просматривая класс Sub, так как значение используется в этом классе.

Теперь что-то подобное не скомпилируется:

public class Super
{
    private static string SomeValue { get { return "Outer"; } }
}

public class Sub
{
    public static string OtherValue { get { return SomeValue; } }
}

Однако * * один тысяча двадцать-одна

public class Super
{
    private static string SomeValue { get { return "Outer"; } }

    public class Sub
    {
        public static string OtherValue { get { return SomeValue; } }
    }
}

все вышеперечисленное прекрасно из-за вложенности классов.

2 голосов
/ 27 февраля 2012

Это связано со значением простых имен , что определяется разделом 7.6.2 спецификации C # 4:

В противном случае для каждого экземпляра типа T (раздел10.3.1), начиная с типа экземпляра непосредственно включающего объявления типа и продолжая с типом экземпляра каждого вложенного класса или объявления структуры (если есть):

  • ...
  • В противном случае, если поиск члена (раздел 7.4) для I в T с аргументами типа K приводит к совпадению:
    • [... здесь не применимо ...]
    • [... здесь не применимо ...]
    • В противном случае результат совпадает с доступом члена (раздел 7.6.4) в форме T.I [...]

Другими словами, компилятор сначала проверяет, является ли Sub.SomeValue допустимым, находит его нет, затем проверяет Super.SomeValue и находит его.

2 голосов
/ 27 февраля 2012

Sub является вложенным классом Super, поэтому любой член Super входит в область действия Sub. Однако эти «унаследованные» члены не являются членами Sub, поэтому Sub.SomeValue недопустимо. Компилятор переводит SomeValue в Super.SomeValue.

1 голос
/ 27 февраля 2012

Внутренний класс наследует часть области видимости внешнего класса. Таким образом, члены в Outer доступны изнутри Sub, но они все еще принадлежат к внешнему классу, поэтому Sub.SomeValue не работает.

Технический термин: лексическая область действия , и это означает, что область действия переменной охватывает «лексический» блок, в котором она находится, то есть она доступна в любом месте блока исходного кода, в котором она определена. , включая подблоки, независимо от владельца времени выполнения. Смотрите также: https://en.wikipedia.org/wiki/Scope_%28programming%29#Lexical_scoping.

Языки, такие как Javascript, Lisp, Haskell и большинство других языков, предназначенных для функционального программирования, широко используют лексическую область видимости, и она тесно связана с другими концепциями FP, такими как применение частичных функций, замыкания и каррирование.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...