如何在C#中创建不可变对象? [英] How to create immutable objects in C#?

查看:109
本文介绍了如何在C#中创建不可变对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#模式验证的最佳做法,最高的投票答案
说:

In a question about Best practices for C# pattern validation, the highest voted answer says:


我倾向于在构造函数中执行所有的验证。这是必须的,因为我几乎总是创建不变的对象。

I tend to perform all of my validation in the constructor. This is a must because I almost always create immutable objects.

您如何在C#中创建不可变对象?你只是使用 readonly 关键字?

How exactly do you create an immutable object in C#? Do you just use the readonly keyword?

如果你想在构造函数中验证您的实体框架是否生成模型类?

How exactly would this work if you want to validate in the constructor of your Entity Framework generated model class?

看起来像下面?

public partial readonly Person
{
    public Person()
}


推荐答案

这里有趣的问题是您的评论中的问题:

The interesting question here is your question from the comments:


什么样的对象你有没有需要在某些时候修改值?我猜不是模特儿班,正确吗?我不得不更改我的数据库中的一个人的名字 - 这不符合这个想法。

What kind of object would you have that you do not need to modify the values at some point? I'm guessing not a model class, correct? I've had to change the name of a person in my database - this wouldn't fit with this idea.

已经不变的东西数字是不变的一旦你有12号,它是12.你不能改变它。如果您的变量包含12,您可以将变量的内容更改为13,但是您正在更改变量,而不是<12> 。

Well, consider things that are already immutable. Numbers are immutable. Once you have the number 12, it's 12. You can't change it. If you have a variable that contains 12, you can change the contents of the variable to 13, but you are changing the variable, not the number 12.

与字符串相同。 abc是abc,它永远不会改变。如果您有一个包含abc的变量,您可以将其更改为abcd,但不会更改abc,这将更改变量。

Same with strings. "abc" is "abc", and it never changes. If you have a variable that contains "abc", you can change it to "abcd", but that doesn't change "abc", that changes the variable.

一个列表怎么样? {12,abc}是12后跟abc的列表,该列表永远不会更改。列表{12,abcd}是不同的列表。

What about a list? {12, "abc"} is the list that is 12 followed by "abc", and that list never changes. The list {12, "abcd"} is a different list.

这就是铁路上的东西。因为在C#中,你可以这么做。您可以说这两个列表之间存在引用身份,如果允许列表在不更改其身份的情况下更改其内容。

And that's where things go off the rails. Because in C# you can do it either way. You can say that there is referential identity between those two lists if lists are allowed to mutate their contents without changing their identity.

当您谈论模特时,您就会在头上打钉。你在建模改变的东西吗?如果是这样,那么可能会用改变的类型对它进行建模。其优点是模型的特征与被建模的系统相匹配。不利的是,做一些像回滚功能这样的功能变得非常棘手,您可以在其中撤消更改。

You hit the nail right on the head when you talk about the "model". Are you modeling something that changes? If so, then it is possibly wise to model it with a type that changes. The benefit of that is that the characteristics of the model match the system being modeled. The down side is that it becomes very tricky to do something like a "rollback" functionality, where you "undo" a change.

也就是说,如果将{12,abc}变为{12,abcd},然后想要回滚突变,那么你怎么做?如果列表是不可变的,你只需要保持这两个值,并选择你想要的那个当前值。如果列表是可变的,那么你必须使撤消逻辑保持在一个撤消功能,它知道如何撤消突变。

That is, if you mutate {12, "abc"} to {12, "abcd"} and then want to roll back the mutation, how do you do it? If the list is immutable you just keep around both values and choose which one you want to be the "current" value. If the list is mutable then you have to have the undo logic keep around an "undo function" which knows how to undo the mutation.

至于你的具体例子,你当然可以创建一个不可变数据库。你如何更改你的不可变数据库中的某人的名字?你没有您创建一个具有所需数据的新的数据库。不可变类型的技巧是高效地执行,而不会复制数十亿字节。不可变数据结构设计需要找到两种几乎相同结构之间共享状态的巧妙方法。

As for your specific example, you certainly can create an immutable database. How do you change the name of someone in your immutable database? You don't. You create a new database that has the data you want in it. The trick with immutable types is to do so efficiently, without copying billions of bytes. Immutable data structure design requires finding clever ways to share state between two nearly-identical structures.

这篇关于如何在C#中创建不可变对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆