Подтвердить что ты не робот

Имеет ли спецификация С# (команда???) Когда-либо рассматриваемый синтаксис создания объекта?

Я никогда раньше не задавал вопрос такого характера, поэтому, если это не подходит для SO, просто не обижайте мои чувства слишком плохо, и я удалю его.

В интересах сохранения всего, что меня интересует как можно ближе к левому краю, я по-прежнему хочу написать что-то вроде:

DataService1.DataEntities dataEntities = new(constructorArg1, ...)

Я думаю, что еще одна причина - мне нравится дополнительная экранная недвижимость, которую я получаю, используя var, когда тип уже присутствует в правой части задания, но мой мозг слишком много лет ищет тип с левой стороны, Опять же, застревание в моих путях - не такая хорошая причина, чтобы пожелать спецификации...

4b9b3361

Ответ 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 };