В C# 12 следующий оператор:
Код: Выделить всё
IList nodes = new List();
Код: Выделить всё
IList nodes = [];
Меня эта функция не особо волнует, но однажды мы включаем C# 12 в магазине, люди неизбежно обнаружат его и начнут использовать.
Согласно документации (и действительно, как это тоже легко можно показать экспериментом), выражения объектов можно использовать для создания экземпляров не только типов, подчиняющихся определенному контракту, но и следующих типов:
- System.Collections.Generic. IEnumerable
- System.Collections.Generic.IReadOnlyCollection
- System.Collections.Generic.IReadOnlyList
- System. Collections.Generic.ICollection
- System.Collections.Generic.IList
Код: Выделить всё
IEnumerable c1 = [1, 2];
IReadOnlyCollection c2 = [2, 3];
IReadOnlyList c3 = [3, 4];
ICollection c4 = [4, 5];
IList c5 = [5, 6];

As it turns out, for mutable interfaces, collection expressions create instances of the List. For immutable interfaces, they create instances of some z__ReadOnlyArray type, which, as a bit of experimentation reveals, is just as defective as List.
Why are they defective? Because their Equals() method does not actually check whether their contents are equal; instead, it defers to object.Equals(), which simply does a reference comparison. So, you may have two instances of List with the exact same contents, and they will report themselves as unequal.
So far I have been able to use the "Banned API Analyzers" to prevent people from using List in the shop, but I do not know how to specify a rule for z__ReadOnlyArray, and even if I could, collection expressions hide the type that is being instantiated, so the analyzers will not flag those instantiations. (They do not flag IList c5 = [5, 6]; which instantiates a List.)
How can I control which types are instantiated by collection expressions when these expressions are used for the creation of collection interfaces?
The documentation explains how to create a new collection type which abides by the necessary contract, but it does not show any means of telling the compiler to use that type when creating instances to back the collection interfaces.
Источник: https://stackoverflow.com/questions/781 ... expression
Мобильная версия