Имеет ли спецификация С# (команда???) Когда-либо рассматриваемый синтаксис создания объекта?
Я никогда раньше не задавал вопрос такого характера, поэтому, если это не подходит для SO, просто не обижайте мои чувства слишком плохо, и я удалю его.
В интересах сохранения всего, что меня интересует как можно ближе к левому краю, я по-прежнему хочу написать что-то вроде:
DataService1.DataEntities dataEntities = new(constructorArg1, ...)
Я думаю, что еще одна причина - мне нравится дополнительная экранная недвижимость, которую я получаю, используя var, когда тип уже присутствует в правой части задания, но мой мозг слишком много лет ищет тип с левой стороны, Опять же, застревание в моих путях - не такая хорошая причина, чтобы пожелать спецификации...
Ответы
Ответ 1
Когда-либо рассматривал проектный комитет С# этот синтаксис создания объекта?
Да, у нас есть. Мы это рассматривали пару лет назад. В качестве доказательства этого утверждения см. Последний абзац моей статьи здесь:
http://blogs.msdn.com/b/ericlippert/archive/2009/01/26/why-no-var-on-fields.aspx
Консенсус команды разработчиков заключался в том, что эта функция была "приятной", но не настолько убедительной, что стоила значительных затрат на проектирование, внедрение, тестирование, документирование и поддержку этой функции.
Я также отмечаю, что комментарии к записи в блоге, с которой я связан, очень отрицательны в отношении этой функции; казалось, что многие люди считают синтаксис непривлекательным. Это также указывает на то, чтобы сделать эту функцию.
Однако предлагаемый синтаксис становится особенно приятным, если вы можете комбинировать его с другими языковыми функциями, которые способствуют краткому объявлению неизменных типов; если мы сделаем такую функцию в гипотетической будущей версии языка, то синтаксис, который вы предлагаете, становится более убедительным.
Замечу еще, что мы вообще сопротивляем свойствам, которые требуют вывода от "снаружи" до "внутри"; мы предпочитаем, чтобы поток информации о типе изнутри. Рассмотрим, например, эту проблему:
M(new(blah));
Предположим, что M имеет две перегрузки, одну из которых принимает C, а другую, которая принимает D. Является ли это "новым C (blah)" или "новым D (blah)"? Это может быть и то. Теперь мы должны проанализировать оба! И если они оба работают, нам нужно выяснить, что лучше.
Ухудшается. Предположим, что у вас есть
M(new(new(blah)));
где снова M принимает C и a D, а C имеет два конструктора, которые берут E или F, а D имеет два конструктора, которые берут G и a H. Какой из:
M(new C(new E(blah)));
M(new C(new F(blah)));
M(new D(new G(blah)));
M(new D(new H(blah)));
и почему?
Когда вы рассуждаете извне внутрь, вы быстро попадаете в "комбинаторные взрывы", где количество анализируемых случаев становится O (c n) в глубине вложенности.
С# делает причину таким образом для lambdas, и это одна из самых сложных частей компилятора, чтобы сделать исполнитель и правильно, поверьте. Мы не хотим добавлять подобную функцию к конструкторам. Если бы мы добавили этот синтаксис, он, вероятно, был бы ограничен сценариями, в которых тип был однозначно известен, анализируя левую сторону объявления переменной или выражения присваивания.
(Как всегда, я отмечаю, что Эрик размышляет о гипотетических будущих языковых функциях в неопубликованных и полностью вымышленных продуктах, которые не имеют графиков или бюджетов, предназначен только для развлекательных целей и не должен рассматриваться как обещание какого-либо конкретного будущего продукта с любой конкретный набор функций.)
Ответ 2
Он отображается слева с обратной стороны выражения. И если выражение не является тривиальным, оно становится довольно уродливым.
Вы можете понять, что выражение делает, просто глядя на выражение почти всегда (кроме какого-либо вывода типа lamda), и это невозможно с вашим синтаксисом. С lamdas выигрыш довольно велик, поэтому сложный вывод - хороший компромисс для lamdas, но добавление этой сложности для такой тривиальной функции - плохой компромисс для простой инициализации переменных.
Вы можете назначить специальный случай для переменной, где крайнее выражение с правой стороны является выражением new
. " Звучит очень нелестно для меня. Тем более, что функция var
уже достигла чего-то очень похожего, будучи более гибкой.
Ответ 3
Если вы хотите создать объект того же типа, что и элемент, используемый для его сохранения, без повторения имени типа, вы можете использовать "Stockton new". Недостатком является то, что вам нужно повторить имя члена в инициализации. Вот как это выглядит:
class Program
{
private static T New<T>(out T item) where T : new()
{
item = new T();
return item;
}
static Dictionary<Int32, Int32> _member = New(out _member);
static void Main(string[] args)
{
Dictionary<Int32, Int32> local = New(out local);
}
}
Кроме того, мы можем расширить этот метод для создания конкретных классов для соответствующих интерфейсов с несколькими простыми перегрузками:
public static IDictionary<TKey, TValue> New<TKey, TValue>(out IDictionary<TKey, TValue> item)
{
item = new Dictionary<TKey, TValue>();
return item;
}
public static IList<T> New<T>(out IList<T> item)
{
item = new List<T>();
return item;
}
Теперь вы можете написать это:
IDictionary<Int32, Int32> local = New(out local);
Мерзость, любопытство или полезный метод? Вы решаете.
Ответ 4
Не уверен в этом, но если вы хотите держать вещи влево, вы можете вместо этого использовать:
var dataEntities = new DataService1.DataEntities(constructorArg1, ...)
Ответ 5
Также как насчет наличия:
DataType dt;
Точно так же, как:
DataType dt = new DataType();
И затем:
DataType dt = { ParamOne = 1, ParamTwo = 2 };
То же, что и:
DataType dt = new DataType(){ ParamOne = 1, ParamTwo =2 };