我一直想知道这个问题,并且未能找到关于这个问题的很多评论,而且我自己也未能得出结论.
在创建对象时,最好的做法是使对象在暴露数据和允许操作数据方面尽可能地受到限制.如果您可以使对象不可变,尤其是在多线程应用程序中,那么最好这样做.
话虽如此,C#似乎更倾向于不遵循此规则的开发人员,允许类的定义更简单,更重要的是,更容易维护.
采用以下只读不可变类:
public class ActiveDirectoryUser
{
private readonly string firstName, lastName, office, username, email;
public ActiveDirectoryUser(string firstName, string lastName, string office, string username, string email)
{
this.firstName = firstName;
this.lastName = lastName;
this.office = office;
this.username = username;
this.email = email;
}
public string FirstName
{
get { return firstName; }
}
public string LastName
{
get { return lastName; }
}
...
public string Email
{
get { return email; }
}
}
Run Code Online (Sandbox Code Playgroud)
并将其与下面更简单的示例进行比较,该示例不是只读的.
public class ActiveDirectoryUser
{
public string FirstName
{
get;
set;
}
public string LastName
{
get;
set;
}
...
public string Email
{
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
可以通过以下方式实例化:
ActiveDirectoryUser user =
new ActiveDirectoryUser
{ FirstName= "Sam", LastName = "Shiles", ..., Email ="Sam@shiles.com" };
Run Code Online (Sandbox Code Playgroud)
鉴于定义更简单,代码行数越少,开发人员错误的可能性越小,另一个开发人员可以轻松理解代码(特别是对于比我们的简单示例更真实的示例),是创建正确代码的价值只读,不可变对象,值得花费?
此外,其他人是否认为使用自动esq语法可以更轻松地在C#中创建不可变对象,例如:
public string FirstName {get; readonly set;}
Run Code Online (Sandbox Code Playgroud)
鉴于定义更简单,代码行数越少,开发人员错误的可能性越小,另一个开发人员可以轻松理解代码(特别是对于比我们的简单示例更真实的示例),是创建正确代码的价值只读,不可变对象,值得花费?
是.
我注意到没有什么能阻止你说
int Foo { get; private set; }
Run Code Online (Sandbox Code Playgroud)
然后仅在构造函数中使用setter,以保证属性的不变性.你只是没有得到漂亮的对象初始化器语法,但你可以很容易地创建一个构造函数.
另外,其他人是否相信使用自动esq语法可以更轻松地在C#中创建不可变对象...
是.特别是,C#语言设计团队认为.
C#3.0增加了许多使C#成为"不可变的友好"语言的特性:匿名类型,查询理解和表达式树特别鼓励不可变数据"功能"编程风格.它还添加了一些功能,使C#成为一种"可变性友好"的语言:自动属性,对象初始化器和类型推断数组.
语言设计团队非常清楚,后面这些特性使得在DLR团队制作一个庞大的不可变表达式树类型库的同时,更容易创建可变对象.讽刺的是他们没有丢失,我可以向你保证.
在语言设计团队中有许多提议可用于制作不可变对象的更好的语法糖.事实上,需要可变性的对象初始化器具有与匿名类型初始化器几乎相同的语法,这是不可变的,是探索的明显起点,但不是唯一的.
所有这一切,当然,首先,我不再代表语言设计团队发言,其次,在Roslyn项目之外没有宣布未来的C#版本.因此,关于该语言的假设未来版本的可能特征集的推测仅仅是:我的推测.