C#规范(团队?委员会?)是否曾考虑过这种对象创建语法?

我之前从未发过这种性质的问题,所以如果它不适合SO,那就不要伤害我的感情太糟糕了,我会删除它。

为了尽可能保持我所关心的一切尽可能接近左边距,我一直希望能写下这样的东西:

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

我认为另一个原因是我喜欢通过使用var得到的额外屏幕空间,当类型已经出现在作业的右侧时,但我的大脑有太多年来在左侧寻找类型。 再说一次,被困在我的方式并不是一个很好的理由,希望有一个规范……

C#设计委员会是否曾考虑过这种对象创建语法?

是的我们有。 几年前我们考虑过它。 作为此声明的证据,请参阅我的文章的最后一段:

http://blogs.msdn.com/b/ericlippert/archive/2009/01/26/why-no-var-on-fields.aspx

设计团队的共识是,这是一个“很好的”function,但不足以引起设计,实施,测试,记录和维护function的相当大的成本。

我还注意到,我链接到的博客条目的评论对该function非常不利; 似乎很多人发现语法没有吸引力。 这也是反对做这个function的要点。

但是,如果您可以将其与其他语言function相结合,以促进简单的不可变类型声明,则所提出的语法会变得特别好; 如果我们在假设的未来版本的语言中执行此类function,那么您提出的语法将变得更加引人注目。

我进一步注意到,我们通常会抵制需要从“外部”到“内部”进行推理的特征; 我们更喜欢从内到外的类型信息流。 考虑一下这个问题:

 M(new(blah)); 

假设M有两个重载,一个采用C,一个采用D.是“新C(blah)”还是“new D(blah)”? 它可能是。 现在我们要分析两者! 如果他们都工作,那么我们必须找出哪个更好。

它变得更糟。 假设你有

 M(new(new(blah))); 

其中M取C和D,C有两个构造函数取E或F,D有两个构造函数取G和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 )。

C#确实以这种方式推理lambdas,这是编译器中最难实现的性能之一,相信我。 我们并不急于为构造函数添加类似的function。 如果我们要添加这种语法,它可能仅限于通过分析变量声明或赋值表达式的左侧明确知道类型的场景。

(与往常一样,我注意到Eric对于没有时间表或预算的未经宣布且完全虚构的产品中假设的未来语言特征的思考仅用于娱乐目的,不应被视为对具有任何特定function的任何特定未来产品的承诺组。)

它从左侧向后推断到表达式。 如果表达是非常微不足道的话,会很快变得丑陋。

您几乎总是可以通过查看表达式本身来理解表达式的作用(除了一些lamda类型推断),这对于您的语法是不可能的。 对于lamdas,增益非常大,因此复杂的推理对于lamdas来说是一个很好的权衡,但是为简单的变量初始化添加这种复杂function是一个不好的折衷。

您可以使用特殊情况“赋值给变量,其中右侧的最右侧表达式是一个new表达式。” 对我来说听起来非常不优雅。 特别是因为varfunction已经实现了非常相似的function,同时更加灵活。

如果要创建与用于存储它的成员相同类型的对象而不必重复类型名称,则可以使用“Stockton new”。 缺点是你必须在初始化中重复成员名称。 这是它的外观:

 class Program {    private static T New(out T item) where T : new()    {      item = new T();      return item;    }    static Dictionary _member = New(out _member);    static void Main(string[] args)    {      Dictionary local = New(out local);    } } 

此外,我们可以扩展此方法,为相应的接口创建具有几个简单重载的具体类:

 public static IDictionary New(out IDictionary item) {   item = new Dictionary();   return item; } public static IList New(out IList item) {   item = new List();   return item; } 

现在你可以这样写:

 IDictionary local = New(out local); 

憎恶,好奇或有用的技巧? 你决定。

不确定,但如果你想把事情保持在左边,你可以改用:

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

如何拥有:

 DataType dt; 

意思是:

 DataType dt = new DataType(); 

然后:

 DataType dt = { ParamOne = 1, ParamTwo = 2 }; 

是相同的:

 DataType dt = new DataType(){ ParamOne = 1, ParamTwo =2 };