gpt4 book ai didi

c# - 在 C# 9 记录上使用 "with"时忽略特定字段?

转载 作者:行者123 更新时间:2023-12-03 15:50:44 24 4
gpt4 key购买 nike

创建 C# 9 的新实例时 record通过使用 with关键字,我想忽略一些字段,而不是将它们复制到新实例中。
在以下示例中,我有一个 Hash属性(property)。因为它的计算成本非常高,所以它只在需要时计算然后缓存(我有一个非常不可变的记录,所以对于一个实例,哈希永远不会改变)。

public record MyRecord {

// All truely immutable properties
public int ThisAndManyMoreComplicatedProperties { get; init; }
// ...

// Compute only when required, but then cache it
public string Hash {
get {
if (hash == null)
hash = ComputeHash();
return hash;
}
}

private string? hash = null;
}
打电话时
MyRecord myRecord = ...;
var changedRecord = myRecord with { AnyProp = ... };
changedRecord包含 hash来自 myRecord 的值,但我想要的是默认值 null再次。
有机会标记 hash字段为“ transient ”/“内部”/“真正私有(private)”......,还是我必须编写自己的复制构造函数来模仿这个功能?

最佳答案

我找到了一种解决方法:您可以(ab)使用继承将复制构造函数分成两部分:手动部分仅适用于 hash (在基类中)和派生类中自动生成的复制所有有值(value)的数据字段。
这具有抽象出散列(非)缓存逻辑的额外优势。这是一个最小的例子( fiddle ):

abstract record HashableRecord
{
protected string hash;
protected abstract string CalculateHash();

public string Hash
{
get
{
if (hash == null)
{
hash = CalculateHash(); // do expensive stuff here
Console.WriteLine($"Calculating hash {hash}");
}
return hash;
}
}

// Empty copy constructor, because we explicitly *don't* want
// to copy hash.
public HashableRecord(HashableRecord other) { }
}

record Data : HashableRecord
{
public string Value1 { get; init; }
public string Value2 { get; init; }

protected override string CalculateHash()
=> hash = Value1 + Value2; // do expensive stuff here
}

public static void Main()
{
var a = new Data { Value1 = "A", Value2 = "A" };

// outputs:
// Calculating hash AA
// AA
Console.WriteLine(a.Hash);

var b = a with { Value2 = "B" };

// outputs:
// AA
// Calculating hash AB
// AB
Console.WriteLine(a.Hash);
Console.WriteLine(b.Hash);
}

关于c# - 在 C# 9 记录上使用 "with"时忽略特定字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66136363/

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