如何解决具有委托属性的C#记录
在尝试C#9记录时,我遇到了一个非常奇怪的行为。我的记录如下:
record MyRecord(Func<MyRecord> SomeAction,string Name)
{
public MyRecord(string name) : this(null,name)
{
SomeAction = Foo;
}
// Foo returns 'this' with SomeAction changed to Bar
MyRecord Foo()
{
Console.WriteLine("Foo: " + SomeAction.Method.Name);
return this with { SomeAction = Bar };
}
MyRecord Bar()
{
Console.WriteLine("Bar: " + SomeAction.Method.Name);
return this;
}
}
我这样使用它:
class Program
{
static void Main(string[] args)
{
var r = new MyRecord("Foo");
Console.WriteLine(r.ToString());
r = r.SomeAction();
r = r.SomeAction();
r = r.SomeAction();
}
}
我期望的输出是
Foo: Foo
Bar: Bar
Bar: Bar
但是,我得到的实际输出是:
Foo: Foo
Bar: Foo
Foo: Foo
这是错误还是我错过了什么?
解决方法
return this with { SomeAction = Bar };
捕获原始记录Bar
,而不捕获更新的记录。并且在原始记录中,SomeAction.Method.Name
是Foo
。由于Bar
返回this
,并且Bar
是原始记录的Bar
,因此第二行返回原始记录,这解释了为什么第三行与原始记录相同。首先。
如果我们这样重写它,将会更容易理解:
class Program
{
static void Main(string[] args)
{
var r = new MyRecord("Foo");
Console.WriteLine(r.ToString());
var r1 = r.SomeAction(); // calls r.Foo,returns new instance of record,capturing r.Bar
var r2 = r1.SomeAction(); // calls r.Bar,and returns r.
var r3 = r2.SomeAction(); // calls r.Foo,capturing r.Bar
}
}
要获得预期的行为,您必须执行以下操作:
record MyRecord(Func<MyRecord> SomeAction,string Name)
{
public MyRecord(string name) : this(null,name)
{
SomeAction = Foo;
}
// Foo returns 'this' with SomeAction changed to Bar
MyRecord Foo()
{
Console.WriteLine("Foo: " + SomeAction.Method.Name);
MyRecord updated = null;
updated = this with { SomeAction = () => updated.Bar() };
return updated;
}
MyRecord Bar()
{
Console.WriteLine("Bar: " + SomeAction.Method.Name);
return this;
}
}
但是我不推荐这种方法-很难遵循。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。