Re[3]: Багофича C# - object initializer
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.24 14:47
Оценка: 2 (1) +1
Здравствуйте, Baiker, Вы писали:
B>Это "объяснение" никак не объясняет, почему тогда виден P2!
Он не "виден", он — часть инициализатора.
Вы же заметили, что в object initializer нельзя слева написать произвольное lvalue? А только свойства инициализируемого объекта?

B>Кроме того, OI — это вам не "скобочки для if" — это специфическая часть, которая работает (у MS) только после new.

Всё верно. И она работает предсказуемым, понятным, и устойчивым к мелким изменениям образом.

B>А накой ляд тогда делать вообще OI, если он такой кривой???

Для упрощения инициализации объектов с большим количеством свойств, лишь малая часть которых нужна в каждом конкретном случае. Ваш К.О.
B>Вопрос-уточнение: мне не интересно, что думал Хлипперт и как конкретно он реализовал эту багофичу. С инженерной точки зрения что мешает видеть P1 и P?
То, что это принесёт больше вреда, чем пользы.

B>Наверное, может надо ПОДУМАТЬ и реализовать?

Может быть. Пока что видно, что ПОДУМАТЬ не желаете как раз вы.

Я сейчас не могу спонталыку просто взять и углубиться в тему компиляторостроения, но если вы приведёте пример такого вот "не очень понятно", то можно поговорить хотя бы о часностях.
B>Опережающий ответ:
B>1. Никто не сказал, что можно будет делать вложенные иниты.
И как вы собираетесь их запретить? На всякий случай поясню, что Object Initializer — это expression. И его, естественно, можно поставить в любое место, где нужен expression.
То есть примерно везде — включая объемлющий object initializer.
B>В конце концов, 99.999999% кода — это как раз простые донельзя конструкции одного уровня.
Основная ценность object initializer — как раз конструирование сложных деревьев объектов. Если у вас простая линейная конструкция, то вам не нужен никакой object initializer — просто напишите цепочку присваиваний свойств.

B>2. Если они будут вложенные и как-то конфликтовать, ВСЕГДА можно посидеть и придумать какое-то интересное решение.

Проблема не в том, чтобы придумать решение. А в том, чтобы это решение не приводило к трудноуловимым багам и WTF. В том числе и в corner cases.

Вот вам простой пример. Версия кода 1:
public class Foo
{
  public string DisplayName {get;set;} 
  public int Number {get; init;}
  public Foo(int number)
  { 
    Number = number;
    DisplayName = number.ToString();
  }
}

public class Bar
{
  public string Name {get; init;}
  public List<Foo> Foos {get; } = new();
  public Bar(int seed) => Name = $"Bar #{new Random(seed).Next()}";
}

public class Program
{
  public static void Main()
  {
    var b = new Bar(42) {
      Foos = {
        new Foo(1) { DisplayName = Name + ":" + Number},
        new Foo(2) { DisplayName = Name + ":" + Number}
      }
    };
  }
}

вроде всё хорошо, да? Name берётся из "текущего" Bar, Number — из "текущего" Foo.
Теперь автор класса Foo, который ничего не знает о коде Main (и, может быть, даже о коде Bar) публикует версию 2, добавляя невинно выглядящее свойство:

public class Foo
{
  public string Name {get;set;}
  public string DisplayName {get;set;}
  public int Number {get; init;}
  public Foo(int number)
  { 
    Number = number;
    Name = number.ToString();
    DisplayName = number.ToString();
  }
}

Автор Main забирает апдейт, компилирует. Всё успешно. Когда он получит баг репорт, он долго пытается понять, почему хорошо отлаженный код вдруг стал выдавать какую-то ересь.
Но вопрос даже не в этом — ну, допустим, он понял, в чём дело. Что ему теперь делать? Как вы предлагаете ему писать код Main так, чтобы он работал как в предыдущем случае?

B>Главное — БАЗОВАЯ ЛОГИКА должна быть инженерная, а не "у нас тут индусокод и вот так исторически сложилось".

Совершенно верно. Базовая логика как раз инженерная.

B>В конце концов, для чего вообще придумывать фичи, кроме как для УДОБСТВА ПРОГРАММИСТА? И на поверку оказалось, что OI-сахарок — чёрте что и полностью обламывает прямую логику разработчика.

Обламывает он только лично вас — и то потому, что вы вместо изучения инструмента придумываете неудачные варианты того, как он мог бы (а точнее — не мог бы) работать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.