对象初始化程序强制编译错误

本文关键字:编译 错误 初始化 程序 对象 | 更新日期: 2023-09-27 18:29:33

在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#风格。

Obj p = new Obj(1, 2, 3,...n); // too many properties to be pretty

对象初始化程序强制编译错误

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

对象初始值设定项实际上不应该被认为是编写构造函数的替代方案。

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

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

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

即使可以,对象的使用者也可以提供默认值(0,null,…)。根据您的需要,考虑在关键时刻验证对象状态(例如,在将其保存到数据库之前)。

如果您采用该路线,请查看IDataErrorInfo接口。

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

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

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

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

A) 其中只有一个应该有setter或

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

这是一个设计问题,而不是语言问题。你不能强迫初始值设定项语法以不同于规范的方式工作。

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

代码不应该是"漂亮的",它应该是有效的。即便如此,一个只接受几个参数的构造函数还是"丑陋"的?嗯?不要相信那些时髦的废话,要编写有效且运行良好的代码。

我能看到实现这一点的唯一方法是,当对象初始值设定项完成时,是否引发了一些事件(或等效事件)。当前有一个"连接"请求,请求具有此效果。

不幸的是,我没有入选.NET4.5:

谢谢你的建议。

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

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

再次感谢!

Mads Torgersen,C#语言PM

也许它会进入.NET5+。

代码契约是什么?。这不仅可以断言您分配了一个值,还可以指定有效的范围。

或者,对于只使用调试构建的运行时检查,您可以使用debug.Assert(…)调用来实现与上面相同的功能。