我们如何看待在C#中将属性用作对象初始值设定项?
我想知道人们如何在C#中使用属性作为对象初始化器。由于某种原因,这似乎打破了构造函数的基本原理。
一个例子...
public class Person { string firstName; string lastName; public string FirstName { get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName= value; } } }
然后用.....进行对象初始化
Person p = new Person{ FirstName = "Joe", LastName = "Smith" }; Person p = new Person{ FirstName = "Joe" };
解决方案
恕我直言,它的甜蜜。大多数对象是使用默认构造函数进行更新的,并且在运行之前必须设置一些属性。因此,对象初始值设定项使针对那里的大多数对象进行编码变得更加容易。
我们在这里看到的是编译器提供的一些语法糖。实际情况下,它实际上是这样的:
人p =新人(名字="乔",姓="史密斯");
Person _p = new Person(); _p.FirstName = "Joe"; _p.LastName = "Smith"; Person p = _p;
因此,恕我直言,我们并没有真正破坏任何构造函数的基础,而是使用了不错的语言构件来简化可读性和可维护性。
我认为总体而言,它很有用,尤其是与自动属性一起使用时。
当属性所做的事情超出获取/设置的范围时,可能会造成混淆。
希望这将导致更多方法,并减少对属性的滥用。
对于从语言集成查询(linq)返回的投影类,这也是非常必要的
var qry = from something in listofsomething select new { Firstname = something.FirstName, Lastname = something.Surname }
对象初始化程序绝不会替代构造函数。构造函数定义了创建类实例时必须遵守的协定。
语言中对象初始化程序的主要动机是支持匿名类型。
var v = new { Foo = 1, Bar = "Hi" }; Console.WriteLine(v.Bar);
对象初始化程序有助于减少编码复杂性,因为我们无需创建六个不同的构造函数即可为属性提供初始值。在我的书中,减少冗余代码的任何事情都是积极的。
我相信将该功能添加到语言的主要原因是为了支持LINQ的匿名类型。
我在代码审查中建议的Nescio想法得到了补充,它积极地追捕了财产访问者中昂贵的透明操作,例如DB往返。
由于我们已经在使用新的Csyntax,因此不妨同时使用自动属性,只是为了使代码更加优美:
而不是这样:
string firstName; public string FirstName { get { return firstName; } set { firstName = value; } }
用这个:
public string FirstName { get; set; }
构造函数只应真正具有构造对象所需的参数。对象初始化程序只是将值分配给属性的便捷方法。我尽可能使用对象初始化程序,因为我认为这是一种整齐的语法。
如果要强制使用构造函数,可以将对象的默认无参数构造函数设置为private,而仅将一些强制的构造函数保留为public:
public class SomeObject { private SomeObject() {} public SomeObject(string someString) //enforced constructor {} public string MyProperty { get; set; } }
使用上面的定义,这将引发错误:
var myObject = new SomeObject { MyProperty = "foo" } //no method accepts zero arguments for constructor
当然,并非所有情况都可以做到这一点。例如,序列化要求我们具有一个非私有的默认构造函数。
不是我们最初的问题,但仍然...
课程声明可以写成:
public class Person { public string FirstName { get; set; } public string LastName {get; set; } }
如果是我的代码,则可能会有一个名称为Name的对象,其字段为First和Last。
我对他们不满意。我认为它们没有在构造函数中占有一席之地,否则MS应该找回并重构它们,以允许我们以私密方式使用它们。如果我构造一个对象,我想传递一些PRIVATE数据。我希望它一次从外界设置,仅此而已。使用对象初始化器,我们可以允许更改传入构造函数的值。
也许将来他们会改变这一点。