C# 对象初始值设定项强制编译错误

C# 对象初始值设定项强制编译错误,c#,object,initialization,compiler-warnings,initializer,C#,Object,Initialization,Compiler Warnings,Initializer,在C#中使用对象初始值设定项时,是否可能强制执行规则或引发错误?如果对象已初始化但缺少某个属性,我希望抛出编译器错误或警告 public class Party { public string Name { get; set; } public string Date { get; set; } public Location Location { get; set; } } public class SignUpForParty { public void D

在C#中使用对象初始值设定项时,是否可能强制执行规则或引发错误?如果对象已初始化但缺少某个属性,我希望抛出编译器错误或警告

public class Party
{
    public string Name { get; set; }
    public string Date { get; set; }
    public Location Location { get; set; }
}

public class SignUpForParty
{
    public void DoSomething()
    {
        Party party = new Party()
        {
            Name = "New Years Party!",
            Date = "Dec 31, 1999"
            // Show WARNING/ERROR here because no Location given
        };
    }
}
本质上,我正在寻找一种方法来确保Party类型的所有对象都是使用每个实例的有效数据创建的

显然,我可以使用重载构造函数来实现这一点,但在某些情况下,我有很多属性,编写与之匹配的构造函数很麻烦。我想要更干净的C#风格


不能强制使用对象初始值设定项初始化每个属性

即使可以,对象的使用者也可以提供默认值(0,null,…)。根据您的需要,考虑在关键时刻验证对象状态(例如,在它可以被保存到数据库之前)。
如果您选择该路线,请查看界面。

如果您的类型在仅设置了两个属性时无效,则需要修复您的设计,而不是发出错误

您提供了一个默认构造函数,它告诉我在初始化后使用对象不需要设置任何东西。同样,为每个属性提供getter和setter,隐式地告诉类的用户可以设置,但不能设置其他属性

如果不是这样,那么我建议您提供一个构造函数,强制我提供所有三个值。是的,我仍然可以使用
(null,null,null)
,但是您可以检查并抛出错误

此外,如果PropertyA依赖于PropertyB,则

A) 他们中只有一个应该有二传手,或者

B) 在每个值的setter中都应该有逻辑,以便在值更改后正确初始化另一个

这是一个设计问题,不是语言问题。您不能强制初始值设定项语法与规范的工作方式不同

Obj p=新的Obj(1,2,3,…n);//太多的属性不好看

代码不应该是“漂亮的”,它应该是有效的。即使这样,一个只接受几个参数的构造函数还是“丑陋”的?嗯?不要相信那些时髦的废话,要编写工作正常的代码

显然,我可以使用重载构造函数来实现这一点,但在某些情况下,我有很多属性,编写与之匹配的构造函数很麻烦。我想要更干净的C#风格

对象初始值设定项真的不应该被认为是编写构造函数的替代方法

如果您有这样的需求,那么应该始终在类型中包含构造函数。创建一组默认构造函数(或在一个构造函数上使用可选参数)是一个好主意,它至少可以保证对象始终以有效、有意义的状态创建


对象初始值设定项对可选属性很有帮助,但不应依赖于您的类型本身的要求。

我看到这一实现的唯一方法是在对象初始值设定项完成时是否引发了某些事件(或等效事件)。目前有一个类似的例子

不幸的是,我没有入选.NET 4.5:

谢谢你的建议

这是一个很好的想法,它有一个很好的特性,即它不会添加到语言表面-它只是使对象初始值设定项更智能。原则上,这可能会使它成为一个突破性的变化,但这是我们可以研究的

不幸的是,我们无法在当前正在构建的版本中添加更多内容,因此我将解决此版本无法修复的问题。不过,我将在我们的功能列表中捕获建议,以供将来讨论

再次感谢

Mads Torgersen,C#语言项目经理

也许它会进入.NET5+。

怎么样?。这不仅表明您已经分配了一个值,而且还可以指定有效的范围


或者,对于仅在运行时使用调试版本进行检查,您可以使用调用来实现与上面相同的功能。

您可以将每个构造函数参数放在自己的行中,这看起来非常相似。你提到了构造函数重载,但你还说你希望设置所有属性,这表明只有一个uber-constructor。谢谢你的回答。我混淆了对象启动器和构造函数。我想要两个世界中最好的一个——构造一个具有强制的对象,但是使用简单的对象启动器样式。我不想成为一群优步的建设者。@reed copsey的想法在我的场景中也是正确的,需要的东西应该在构造函数中,可选的东西应该留给发起者。这是一个非常有趣的想法。在很多方面,这几乎就是我想要的。@davideath-不幸的是,目前没有提供此功能的解决方案,因此我只能建议对connect请求进行投票,希望它能进入下一个版本。考虑到我们目前的限制,我认为今天唯一可行的办法就是使用建议的想法。也许很快吧。大家都同意了,谢谢。“…你提供了一个构造函数,它迫使我提供所有三个值”-我的问题可能会通过问“我可以提供带有初始值设定项的构造函数的行为吗?”得到更好的理解,我知道,这是否定的。
Obj p = new Obj(1, 2, 3,...n); // too many properties to be pretty