Дизайн и эволюция свойств в C# (часть 7)
Открытые проблемы
В завершение нашей экскурсии по версиям языка C#, предлагаю посмотреть в будущее и рассмотреть некоторые из популярных проблем, которые по-прежнему не решены в языке.
Что C# 7.0 нам уготовит?
На момент написания статьи сложно судить о наборе новых языковых инструментов, но если взглянуть на список предложений, то на свойства может повлиять возможность определять типы-записи, например:
class Person(string name : Name, int age : Age) {
// that's all!
}
Такая запись объявления класса с первичным конструктором может компилироваться в автоматические определения авто-свойств и их инициализацию тривиальным конструктором:
class Person {
public Person(string name, int age) {
this.Name = name;
this.Age = age;
}
public string Name { get; }
public int Age { get; }
}
Открытыми вопросами остаются возможность контроля изменяемости генерируемых авто-свойств (если они будут генерироваться вообще), возможность изменения их уровня доступа или аннотации некоторым аттрибутом. Все эти проблемы возникают из-за введения радикально нового способа объявления свойства, совершенно не имеющим ничего общего с обычными объявлениями членов класса.
Стоит ли усложнять и без того сложный C#, вводя еще один синтаксический способ определения свойства ради краткости объявления структуры данных? Если вы дочитали статьи до этого момента, то может казаться что новую разновидность объявления вводить не стоит. Однако если вам приходилось переписывать много кода с кортежами на именованые типы, то вы будете склоняться к пользе типов-записяй, не смотря на добавленную сложность…
Понятие “backing-поля”
- “хочу свойства рядом с полями”, никто не знает что есть “backing field”
- “хочу объявление поля внутри свойства”
Проблема INotifyPropertyChanged
- TODO
Свойства как значения
- TODO
Делегация реализации свойства
Misc
- фичи IDE должны проверять и поля, и свойства
- [DebuggerDisplay] - приходится скрывать поля
- порядок аксессоров произволен (добавить в C# 1.0)
- нельзя сделать делегат из свойства (добавить в C# 1.0)
delegate string ReturnsString();
void M(Person person) {
ReturnsString delegate1 = Console.RealLine;
ReturnsString delegate2 = person.Name; // ???
}
type Person = { firstName: string
lastName: string }
type Person with
member this.fullName with get() = this.firstName + " " + this.lastName
let p = { firstName = "Alan"; lastName = "Turing" }
printfn "%s" p.fullName
TODO: em dash TODO: …