Очередные дополнения к C# 6 (27 августа)
30.08.2014
|
AndrewVK |
Первичные конструкторы теперь разрешены и у структур.
P.S. Кстати, как то из презентаций убежал синтаксис, позволяющий задавать тело первичного конструктора. Выглядит так:
P.S. Кстати, как то из презентаций убежал синтаксис, позволяющий задавать тело первичного конструктора. Выглядит так:
class MyClass(int x, int y)
{
private readonly int _z;
{
_z = x + y;
}
}
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
30.08.2014 39 комментариев |
AVK>P.S. Кстати, как то из презентаций убежал синтаксис, позволяющий задавать тело первичного конструктора. Выглядит так:
AVK>
фигурные скобки после точки с запятой?
S>фигурные скобки после точки с запятой?
Да. А что тебя смущает?
AVK>Здравствуйте, samius, Вы писали:
S>>фигурные скобки после точки с запятой?
AVK>Да. А что тебя смущает?
Пардон, я не правильно воспринял пример. Увидел код, не сильно вдаваясь в текстовое описание того, чего именно это пример, подумал что вижу тело инициализатора поля _z. Потому и удивился разделителю между объявлением поля и инициализатором.
Но конструктор одинаковым образом относится ко всем полям, объявленным в классе. Поэтому точка с запятой логична.
Прошу прощения за невнимательность.
AVK>P.S. Кстати, как то из презентаций убежал синтаксис, позволяющий задавать тело первичного конструктора. Выглядит так:
AVK>
С точки зрения читабельности кода — это лютый АД!
Особенно учитывая, что эти скобки можно поставить в любом месте класса. А если еще учесть, что класс может быть partial
AB>С точки зрения читабельности кода — это лютый АД!
AB>Особенно учитывая, что эти скобки можно поставить в любом месте класса. А если еще учесть, что класс может быть partial
В Java сто лет так, особо никому не надо. По большей части используется так:
То есть ничего другого и нет и читаемость не страдает.
GIV>
GIV>То есть ничего другого и нет и читаемость не страдает.
Речь идет не о создании объектов (и их инициализации по месту), а об описании классов. Прочти исходное сообщение.
AB>Здравствуйте, GarryIV, Вы писали:
GIV>>
GIV>>То есть ничего другого и нет и читаемость не страдает.
AB>Речь идет не о создании объектов (и их инициализации по месту), а об описании классов. Прочти исходное сообщение.
А тут и есть описание класса (анонимного) ну и да, зараз и создание.
не понятно: var myStructArray = new MyStruct[count] — выполнится ли конструктор хотя-бы раз?
где первоисточник новости? дайте ссылку
Ф>где первоисточник новости? дайте ссылку
Первоисточник там же, где и раньше:
http://roslyn.codeplex.com/discussions/562559
http://roslyn.codeplex.com/discussions/562558
AVK>P.S. Кстати, как то из презентаций убежал синтаксис, позволяющий задавать тело первичного конструктора. Выглядит так:
Что-то я не уловил всей гениальности замысла В чём профит?
Что от конструкторов в структурах с ломающим поведением типа
и тормозами "new T()" для структур в генерик-методах (теперь default(T) сгенерить нельзя, только Activator.CreateInstance()),
что от борьбы с синтаксическим оверхедом аля
Ну, кроме как новых квестов от ув. nikov?
Вообще, все эти метания шестого шарпа с "а можно записать конструктор так, а свойство так, а тут ещё вот так" и общим счётом пятью равноправными вариантами:
* классика
* X { get; set; }
* X { get; } = x
* X => x;
* new { X = x }; // для анонимных типов
+ гипотетический шестой для описания тюплов не вызывает никакой реакции, кроме как "горшочек не вари".
Такое впечатление, что интерны усыпили Хейлсберга и фигачат код, пока никто не видит
S>Что-то я не уловил всей гениальности замысла В чём профит?
В смысле? Профит в том что можно писать код для primary constructor.
S>Что от конструкторов в структурах
Ээ, т.е. вопрос не к тому что ты процитировал, а к тому что из цитаты удалил? Профит очень простой — консистентность. Чем меньше в языке oddities, тем проще его использовать.
S>что от борьбы с синтаксическим оверхедом аля
S>
Ну вот так. Я сам был несколько удивлен. Но, видимо, такая фича почти ничего не стоила и проблем она тоже не привносит. Что же касается полезности на практике — ну вот написал ты класс с первичным конструктором. А потом понадобилось какую нибудь мелочевку добавить — и надо все перетаптывать. Меня этой "мегафичей" автопроперти изрядно достают. Так что, видимо, это все в рамках борьбы с подобным — проблему с автосвойствами то вполне целенаправленно в этом релизе решают, так зачем подкладывать подобное с другой стороны?
S>* X { get; } = x
S>* X => x;
Это не равноправные варианты. И если х это параметр конструктора, то во втором варианте вообще будет синтаксическая ошибка.
S>* new { X = x }; // для анонимных типов
А это вообще из другой оперы.
S>+ гипотетический шестой для описания тюплов не вызывает никакой реакции, кроме как "горшочек не вари".
С тюплами пока вообще говорить не о чем. То что там народ экспериментирует или просто бредит на тему — это немного другой слой реальности.
Вот то что primary конструкторы это путь к record classes и PM, так это да. Я об этом год назад с Мэдсом беседовал, и он был полностью со мной согласен. Да и в недавнем сообщении тоже вскольз об этом упомянул. Но этот релиз вообще не про выразительные возможности языка. От слова совсем.
S>Такое впечатление, что интерны усыпили Хейлсберга и фигачат код, пока никто не видит
Какие интерны? Там вроде Мэдс пока рулит больше всех, а он на интерна как то не совсем тянет, не? Да и Хэйлсберг, когда на эту тему Липперт прикалывался, говорил что все нормально, он в курсе и не против
S>>Что от конструкторов в структурах
AVK>Ээ, т.е. вопрос не к тому что ты процитировал, а к тому что из цитаты удалил?
Угу, процитировал неудачно.
AVK>Профит очень простой — консистентность. Чем меньше в языке oddities, тем проще его использовать.
С точки зрения нового кода — безусловно да, с точки зрения старого — ломающее поведение, что очень нехорошо. По сути, в c# переизобретают грабли бейсика с null и nothing, которые были одним из основных доводов против конструкторов по умолчанию в структурах. Авторам конечно виднее, но я пока не вижу ни одного выигрышного пункта.
Гарантия, что поля структуры будут инициализированы? Нет, new Struct[1][0] — и приятной отладки. Для классов для подстраховки есть хоть NullReferenceException, для структур нет и его.
Какой-либо выигрыш в производительности? Нет, скорее наоборот, теряем для new T() в генериках. Учитывая nullable-структуры — проблема массовая.
Упрощение обучения? Нет, теперь для структур вместо двух равнозначных default(Struct) и new Struct() мы получили два различных поведения.
Сокращение кода? Тоже нет, теперь в структурах с primary ctor нужно или ставить отладочные ассерты, или периодически ловить ошибки из-за неинициализированной структуры.
AVK>Ну вот так. Я сам был несколько удивлен. Но, видимо, такая фича почти ничего не стоила и проблем она тоже не привносит. Что же касается полезности на практике — ну вот написал ты класс с первичным конструктором. А потом понадобилось какую нибудь мелочевку добавить — и надо все перетаптывать. Меня этой "мегафичей" автопроперти изрядно достают. Так что, видимо, это все в рамках борьбы с подобным — проблему с автосвойствами то вполне целенаправленно в этом релизе решают, так зачем подкладывать подобное с другой стороны?
Ну... это всё-таки проблемы студии, а не языка. Добавить рефакторинг аля решарперовский "to property with backing field" в рослине дело 10-20 минут. А вот добавление фичи из разряда "парой букв меньше писать" аукнется кучей граблей всем — от авторов учебников и парсеров и до поддержки кода с "{ BadCode(); }" где-нибудь в середине класса.
С остальным согласен
S>Ну... это всё-таки проблемы студии, а не языка. Добавить рефакторинг аля решарперовский "to property with backing field" в рослине дело 10-20 минут.
вообще говоря это не аргумент. Дело именно в языке, потому что хотя писать код(большую его часть) за нас может IDE, то вот читать его приходится самим, глазками. И всякий синтаксический шум тут очень мешает.
S>>Ну... это всё-таки проблемы студии, а не языка. Добавить рефакторинг аля решарперовский "to property with backing field" в рослине дело 10-20 минут.
J>вообще говоря это не аргумент. Дело именно в языке, потому что хотя писать код(большую его часть) за нас может IDE, то вот читать его приходится самим, глазками. И всякий синтаксический шум тут очень мешает.
Ну так новая фича "тело конструктора в отрыве от сигнатуры" только добавляет шума, сравни:
Теперь добавляем в код валидацию аргументов, побольше полей, другие конструкторы + вызов базового конструктора — получаем полную ересь. Понятно, что сдуру всё сломать можно, но смысл добавлять промежуточный вариант конструктора, который придётся рано или поздно переписывать в классический?
S>Ну так новая фича "тело конструктора в отрыве от сигнатуры" только добавляет шума, сравни:
S>
S>Теперь добавляем в код валидацию аргументов, побольше полей, другие конструкторы + вызов базового конструктора — получаем полную ересь. Понятно, что сдуру всё сломать можно, но смысл добавлять промежуточный вариант конструктора, который придётся рано или поздно переписывать в классический?
Вообще то первый вариант кода — дурость и есть. Нужно так:
а вот тело для праймари конструктора как раз позволяет не отказыватся от него, если вдруг через пол года понадобится какая нить валидация.
Или я суть претензий не понял?
J>Вообще то первый вариант кода — дурость и есть.
Но мы-то обсуждаем именно его Посмотри пример в начале ветки.
J>а вот тело для праймари конструктора как раз позволяет не отказыватся от него, если вдруг через пол года понадобится какая нить валидация.
А не проще будет
?
Вот это
1-в-1 совпадает с исходным примером, только порядок членов изменён. Поскольку в шарпе порядок не имеет значения — будут писать и так, и так.
Ну и разумеется, ничем принципиально не отличается от
, если не считать невозможность прописать /// <summary /> у конструктора в первом варианте. Ну и порядок присвоения — в первом варианте валидация сработает уже после присвоения.
В общем, нафига так извращаться — я так и не понял.
S>Ну так новая фича "тело конструктора в отрыве от сигнатуры" только добавляет шума, сравни:
А если кода чуть больше?
?
S>Теперь добавляем в код валидацию аргументов, побольше полей, другие конструкторы + вызов базового конструктора — получаем полную ересь.
Никакой ереси мы не получаем. Получаем лучшую читаемость, потому что тело как было, так и осталось, а вот наличие объявления первичного конструктора сразу нам говорит, что у класса только один конструктор и он имеет сразу видимую сигнатуру, не теряющуюся среди методов.
AVK>А если кода чуть больше?
Угу, наконец уловил мысль авторов
Честно говоря, по-прежнему не уверен, что имеет смысл заводить новую конструкцию ради такой мелочи, ну да фиг с ним. Раз сделали — пусть будет.
AVK>Никакой ереси мы не получаем. Получаем лучшую читаемость, потому что тело как было, так и осталось, а вот наличие объявления первичного конструктора сразу нам говорит, что у класса только один конструктор и он имеет сразу видимую сигнатуру, не теряющуюся среди методов.
Кстати, а почему один? Стандарт же позволяет дополнительные конструкторы, если они вызывают primary-конструктор:
или это уже поменялось?
S>Ну... это всё-таки проблемы студии, а не языка.
Это проблемы языка, которые можно отчасти решить студией.
S> Добавить рефакторинг аля решарперовский
Ну давай тогда поотменяем весь синтаксический сахар, заменив на рефакторинги?
S>А вот добавление фичи из разряда "парой букв меньше писать" аукнется кучей граблей всем — от авторов учебников и парсеров и до поддержки кода с "{ BadCode(); }" где-нибудь в середине класса.
Ты преувеличиваешь.
AVK>Первичные конструкторы теперь разрешены и у структур.
А можно узнать, в чём вообще профит от "первичных конструкторов"? Я смотрю и никак не могу понять, где тот многочисленный use case, где я прямо тоннами пишу код и ПК помогает мне его ужать хотя бы в два раза? Что-то мне говорит, что разрабы {непереводимая игра слов с использованием дуба, марихуанны и матери каждого индуса}.
C# с его текущим ПМ скатывается в ОНО — дебильнее фич 6.0 — только Win 8.0 — такой же уродец мира ИТ. И никакие Рослины не помогут, если в голове — опилки.
B>А можно узнать, в чём вообще профит от "первичных конструкторов"?
Уменьшение количества писанины.
B> Я смотрю и никак не могу понять, где тот многочисленный use case, где я прямо тоннами пишу код и ПК помогает мне его ужать хотя бы в два раза?
Насчет разов тебе ничего сказать не могу, но типичные юзкейсы: http://en.wikipedia.org/wiki/Data_transfer_object, http://en.wikipedia.org/wiki/Abstract_syntax_tree
B>C# с его текущим ПМ скатывается в ОНО — дебильнее фич 6.0 — только Win 8.0 — такой же уродец мира ИТ. И никакие Рослины не помогут, если в голове — опилки.
Твой нетрадиционный взгляд на языки большинству здесь уже известен, и обсуждать его смысла не имеет, ты все равно никого не слышишь.
B>>А можно узнать, в чём вообще профит от "первичных конструкторов"?
AVK>Уменьшение количества писанины.
В данном случае уменьшение писанины ЗАПУТЫВАЕТ понимание структуры класса. Пример:
Во-первых, класс пустой. А
сусликпеременные в нём есть! Уже несоответствие "что вижу — что на самом деле".Во-вторых, ну и в чём опять профит-то?? (я про МАССОВЫЙ код) Взяли какой-то узкоспециализированный случай, засунули в язык — всё, радость?
AVK>... типичные юзкейсы: Data_transfer_object, Abstract_syntax_tree
Я понимаю, в теории можно понаписать однострочных DTOшек. Но я боюсь, что даже они — не так просты, как хочется авторам этой "мегафичи". Почему вдруг x и y — private?? А в чём смысл их существования без public доступа? А если я из X хочу проперть, а из Y — поле? А вот для BLToolkit я использую простые классы с паблик полями: классов — много, толку от primary constructors — ноль.
Я это всё к чему — к узконаправленности мышления разрабов. Вроде бы фича есть, вроде бы где-то даже полезна, но я не вижу её полезности для массового прогера — зачем тогда тратить на неё время?? В списке запросов ТЫСЯЧИ просьб, но реализована самая ненужная и неоднозначная. И вот теперь плавно подходим к следующей мысли:
B>>C# с его текущим ПМ скатывается в ОНО...
AVK>Твой нетрадиционный взгляд на языки большинству здесь уже известен, и обсуждать его смысла не имеет, ты все равно никого не слышишь.
Если языки пишут нетрадиционные (в плохом смысле) прогеры, то и сам язык выглядит как п****ое поделие — я в чём виноват? У меня ориентация — десктоп приложения и классический сервер (без всяких WCF/EF) и я даже в таком широком спектре приложений в упор не вижу, чем primary constructor мне поможет.
Автоинициализация пропертей — ДАВНО надо было сделать — дождались. Using статических полей — ещё одна таймбомба на пути "испохабим C# до уровня php".
Клянусь, только сделайте фичу — вас ЗАВАЛЯТ ***ном и критикой И БУДУТ ПРАВЫ. Вот тогда и вспомните btn1
B>В данном случае уменьшение писанины ЗАПУТЫВАЕТ понимание структуры класса.
Нет, не запутывает. Наоборот, явно выделяет довольно важную семантическую составляющую.
B> private int x, y;// ага! здесь ВСЕ мои поля!
Я так понимаю, подробно с первичными конструкторами ты даже не ознакомился. Никакие приватные поля они не создают.
B>Во-вторых, ну и в чём опять профит-то?? (я про МАССОВЫЙ код) Взяли какой-то узкоспециализированный случай
Это не узкоспециализированный случай. Классов с одним конструктором — большинство.
AVK>>... типичные юзкейсы: Data_transfer_object, Abstract_syntax_tree
B>Я понимаю, в теории можно понаписать однострочных DTOшек.
На практике — тоже.
B> Но я боюсь, что даже они — не так просты, как хочется авторам этой "мегафичи". Почему вдруг x и y — private??
Ознакомься с фичей, потом спорь.
B>Если языки пишут нетрадиционные (в плохом смысле) прогеры, то и сам язык выглядит как п****ое поделие — я в чём виноват?
Так где те языки, которые написали традиционные? Можно пример?
B> У меня ориентация — десктоп приложения и классический сервер (без всяких WCF/EF) и я даже в таком широком спектре приложений в упор не вижу, чем primary constructor мне поможет.
Сочувствую.
AVK>Я так понимаю, подробно с первичными конструкторами ты даже не ознакомился. Никакие приватные поля они не создают.
Ошибся слегка, не надо меня так уж гнобить. Просто пример был дурацкий (с хабропомойки взял).
B>>В данном случае уменьшение писанины ЗАПУТЫВАЕТ понимание структуры класса.
AVK>Нет, не запутывает. Наоборот, явно выделяет довольно важную семантическую составляющую.
Запутывает, потому что вводит лишнюю сущность туда, где в ней нет потребности. Что это за такой специальный конструктор "инициализатор полей"? Ну была такая фича у С++ (ага, вот откуда корни — замшелые сипиписники набижали!), но мы теперь что, будем придумывать конструкторы на каждый алгоритм? А если в конструкторе цикл — сделаем "цикл-конструктор"?
Вся несуразность этих сокращений вылезет тогда, когда понадобится улучшать класс — вот тут попрыгает бедолага:
1. Нужно найти не только все конструкторы, но и не забыть взглянуть в заголовок класса — лишнее действие, которое 100% будут забывать.
2. Если понадобится "почти такой же" конструктор, но с действием — хана, значит надо будет лезть вычищать все места "поле = хрень из Прим.Констр." и вносить их в "нормальный" конструктор.
3. Если просто нужен ещё один конструктор, ОБЯЗАТЕЛЬНО надо вызывать Прим.Констр. — компилятор-то напомнит, но нафига козе баян?? Зачем усложнять структуру вызовов?
AVK>Это не узкоспециализированный случай. Классов с одним конструктором — большинство.
Да, но не обязательно большинство составляют "примитивные" конструкторы, где только присваиваются поля!
AVK>Так где те языки, которые написали традиционные? Можно пример?
C# 5.0 (и тот сильно проигрывает Nemerle или D )
Ещё раз, в свете новых знаний, запишу "мегаулучшение кода":
Теперь я правильно понимаю надобность в ПК? Но если речь идёт о ТАКОМ примитиве, я вообще не вижу смысла с ним возиться — возьми T4 и ляпай такие классы вообще не приходя в сознание! Зачем вводить ерунду на уровне языка?
Более того — DTO классы удобнее использовать с public полями (чтобы отдавать их ORM'у), где все primary constructors идут нафиг, ибо можно спокойно записать:
Вообще без единого конструктора!
Да и парсеру не нужно лишний раз напрягаться в объявлении класса — будут ли там параметры после класса или нет.
В общем, фича — грошовая, толку — минимум, а силы — потрачены. Зато interpolated strings задвинули в угол — как же, "нет времени"!
B>Зато interpolated strings задвинули в угол — как же, "нет времени"!
Активно ими занимаемся. Но там есть проблема — как распознать конец interpolated expression, сохранив простой лексер и быстрый инкрементальный парсер, и не используя слишком уродливый синтаксис наподобие \{...\}
N>Активно ими занимаемся. Но там есть проблема — как распознать конец interpolated expression, сохранив простой лексер и быстрый инкрементальный парсер, и не используя слишком уродливый синтаксис наподобие \{...\}
А оно надо? Такие строки большими не будут. Их парсинг и целиком будет миллисекунды занимать.
B>Что это за такой специальный конструктор "инициализатор полей"?
Нет никакого специального конструктора. Есть обычный конструктор, который главный. Как я уже писал — большинство классов имеют ровно один конструктор, и сигнатура этого конструктора неразрывно связана с классом, а не является его дополнением, как методы. Это уже, де-факто, такая семантика. Первичные конструкторы всего лишь позволяют оформить это синтаксически, что весьма и весьма способствует читабельности.
B>1. Нужно найти не только все конструкторы, но и не забыть взглянуть в заголовок класса — лишнее действие, которое 100% будут забывать.
Это, позволь спросить, что за способ просмотра кода такой, когда название и список предков и интерфейсов класса тебе не важен, а вот сигнатура конструктора важна?
B>2. Если понадобится "почти такой же" конструктор, но с действием — хана, значит надо будет лезть вычищать все места "поле = хрень из Прим.Констр." и вносить их в "нормальный" конструктор.
Еще раз — ознакомься с фичей, а потом уже критикуй.
B>3. Если просто нужен ещё один конструктор, ОБЯЗАТЕЛЬНО надо вызывать Прим.Констр. — компилятор-то напомнит, но нафига козе баян??
А вот как раз чтобы не бегать и не искать, что там еще за конструкторы. Первичный конструктор гарантированно вызывается всегда, а все остальные — просто хелперы.
AVK>>Это не узкоспециализированный случай. Классов с одним конструктором — большинство.
B>Да, но не обязательно большинство составляют "примитивные" конструкторы, где только присваиваются поля!
Ты уже забыл что я в стартовом сообщении написал?
AVK>>Так где те языки, которые написали традиционные? Можно пример?
B>C# 5.0
Вот я о том и говорю — что то доказывать тебе бесполезно.
B>Теперь я правильно понимаю надобность в ПК? Но если речь идёт о ТАКОМ примитиве, я вообще не вижу смысла с ним возиться
А я вижу. И куча народа тоже видит. Извини, но твое видение нифига не аргумент.
B> — возьми T4 и ляпай такие классы вообще не приходя в сознание!
Тебе, надеюсь, не надо объяснять почему Т4 это не решение проблемы?
B>Более того — DTO классы удобнее использовать с public полями (чтобы отдавать их ORM'у)
Ага, и автоматом получить mutable state и возможность поломать инварианты. Спасибо, не надо.
B>Зато interpolated strings задвинули в угол — как же, "нет времени"!
И слава богу. Потому что пользы в нормально написанном коде от interpolated string примерно 0 — многоязычие требует почти всегда текстовые константы закатывать в ресурсы.
AVK>И слава богу. Потому что пользы в нормально написанном коде от interpolated string примерно 0 — многоязычие требует почти всегда текстовые константы закатывать в ресурсы.
Серьезно?? Ты свою практику с общемировой не путаешь?
AVK>P.S. Кстати, как то из презентаций убежал синтаксис, позволяющий задавать тело первичного конструктора. Выглядит так:
AVK>
Хочу напомнить, что всё это — исключительно экспериментальные фичи, и нет абсолютно никакой гарантии, что они попадут в релиз C# 6.0.
Извиняюсь что вклиниваюсь, вроде более менее по теме. По мотивам прошлого обсуждения semicolon operator наконец в голове дозрели плюсы предложенного мной дизайна. Описание кратко: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/6504697-block-code-as-value-another-syntax-for-semicolon Собственно дискасс кому есть что предложить в дополнение, ну или почему это нафиг никому не нужно. Прошу проголосовать (по ссылке) кому показалось полезным.
A>Извиняюсь что вклиниваюсь, вроде более менее по теме. По мотивам прошлого обсуждения semicolon operator наконец в голове дозрели плюсы предложенного мной дизайна.
semicolon operator отложили, в этом релизе его не будет.