Багофича C# - object initializer
От: Baiker  
Дата: 21.07.24 19:50
Оценка:
Ребят, столкнулся с какой-то маразматической особенностью C# (на которую у MS конечно же есть объяснения), но моeй инженерной логике она не поддаётся.
Всё очень просто:

class A
{
    public int P = 666;
}

class B : A
{
    public int P1 = 4;
    public int P2;

    public B()
    {
        P = 13;
    }
}

// где-то в коде решили создать класс B:

var b = new B { P2 = P1 + P };// ошибка прокладки между стулом и монитором!


...и..... ннна тебе поддых канпелятором!! В object initializer ни мембера P, ни P1 канпелятор НЕ ВИДИТ!
Что это за маразм?? Что за такой странный контекст вдруг образовался в элементарном инициализаторе?
Я-то (наивный) думал, что {} — это просто сокращение для b.P2 = b.P1 + b.P ! Похоже, мелкомягкие что-то там намудрили под капотом.

Примером выше я хотел иллюстрировать несколько другой маразм:

Форма из WinForms
   Метод()
   {
      var c = new UserControl {
          Left = Width / 2
      };
   }


Здесь в OI свойство Left КАК И ПОЛОЖЕНО — от UserControl, но Width оказывается берётся от самой формы(!!!). С какого перепоя??
Ведь Width должно браться из самого внутреннего контекста, т.е. от UserControl! Что за бредовая логика заставляет MS лезть в объемлющий контекст?

PS
А я ведь ещё на заре этой дебильной фичи предлагал: не надо этой узколобой привязки инициализатора к конструктору!! Надо, чтобы это работало как with в Паскале:

var j = new J();
// какой-то посторонний код
j init {
    .p1 = 3;
    .fn();// ДА! И ВЫЗОВ ФУНКЦИЙ ТОЖЕ!!
    p2 = .p1;
}

var j2 = new J() init {
   .p1 = p2 + 6;
}


Здесь j во-первых может инициализироваться в ЛЮБОМ месте кода, а во-вторых, чётко видно кто и откуда берётся: ".p1" — это внутренний мембер (потому что с точки),
"p2" — мембер из объемлющего контекста. Просто и универсально как лом. Что помешало неумытым "синьорам" с индийских пальм сделать это по-человечески?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.