gpt4 book ai didi

c# - 更改不可变类型的属性

转载 作者:行者123 更新时间:2023-11-30 16:01:22 28 4
gpt4 key购买 nike

我在一个临时的 CQRS 读取存储中存储了不可变类型(查询/读取端,实际上是由一个带有抽象访问层的简单列表实现的,此时我不想使用一个完整的文档数据库)。这些阅读商店包含如下项目:

public class SomeItem
{
private readonly string name;
private readonly string description;

public SomeItem(string name, string description)
{
this.name = name;
this.description = description;
}

public string Name
{
get { return this.name; }
}

public string Description
{
get { return this.description; }
}
}

现在我想更改名称并在第二个命令中更改描述。这些更改应保持当前状态,这意味着对于上面的示例:

// initial state
var someItem = new SomeItem("name", "description");

// update name -> newName
someItem = new SomeItem("newName", someItem.Description);

// update description -> newDescription
someItem = new SomeItem(someItem.Name, "newDescription");

如果您有多个属性,这对我来说确实容易出错……您必须设法保持当前状态。我可以为每种类型添加类似 Clone() 的东西,但我认为/希望有更好的东西,性能好且易于使用,我不想写太多重复的代码(懒惰的程序员)。有什么建议可以改进上面的代码吗? SomeItem 类需要保持不变(通过多个不同的线程传输)。

最佳答案

遗憾的是,C# 中没有简单的方法。 F# 有 with 关键字,你可以看看 lenses,但在 C# 中这一切都有些乏味。我能给你的最好的是这样的:

class SomeItem
{
private readonly string name;
private readonly string description;

public SomeItem(string name, string description)
{
this.name = name;
this.description = description;
}

public SomeItem With
(
Option<string> name = null,
Option<string> description = null
)
{
return new SomeItem
(
name.GetValueOrDefault(this.name),
description.GetValueOrDefault(this.description)
);
}
}

这使您可以像这样进行更新

var newItem = oldItem.With(name: "My name!");

我已经将这种方法与扩展方法和 T4 一起使用,效果很好,但即使您手动编写代码,它也相当可靠——如果您添加一个新字段,则必须将它添加到 With 也是如此,所以它工作得很好。

如果您愿意容忍运行时代码生成和降低类型安全性,还有其他几种方法,但这有点违背 IMO 的原则。

关于c# - 更改不可变类型的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38789031/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com