gpt4 book ai didi

c# - 具有对象初始化器的不可变对象(immutable对象)

转载 作者:行者123 更新时间:2023-12-04 01:19:01 25 4
gpt4 key购买 nike

我对不可变对象(immutable对象)进行了以下尝试:

class MyObject
{
private static int nextId;

public MyObject()
{
_id = ++nextId;
}

private int _id;
public int Id { get { return _id; } }
public string Name { get; private set; }
}

然后,我尝试像这样使用它:
MyObject o1 = new MyObject { Name = "foo" };

但是对象初始化失败,因为 Name的 setter 是私有(private)的。有没有办法解决这个问题,还是我必须在其中一个或另一个之间做出选择?

最佳答案

您不能将对象初始值设定项与不可变对象(immutable对象)一起使用。它们需要可设置的属性。

不可变对象(immutable对象)意味着“创建后不会更改”。制作 Name构造函数参数巧妙地表达了这一原则。

如果对象对于可理解的构造函数来说太复杂了,您也可以使用 Builder 模式。通常,构建器本身将具有可变属性(您可以在对象初始化器中使用),并且其 .Build() 方法将创建实际实例。

编辑(OP):我将添加我自己在这里制作的构建器示例,然后接受这个答案,因为它提出了一个合理的解决方案。

class MyObject
{
public class Builder
{
public Builder()
{
// set default values
Name = String.Empty;
}

public MyObject Build()
{
return new MyObject(Name);
}
public string Name { get; set; }
}

private static int nextId;

protected MyObject(string name)
{
Id = ++nextId;
Name = name;
}

public int Id { get; private set; }
public string Name { get; private set; }
}

然后,您可以使用以下内容构造它的实例:
MyObject test = new MyObject.Builder { Name = "foo" }.Build();

编辑 :这是我对模式的看法:
public abstract class Builder<T>
{
public static implicit operator T(Builder<T> builder)
{
return builder.Build();
}

private bool _built;

public T Build()
{
if(_built)
{
throw new InvalidOperationException("Instance already built");
}

_built = true;

return GetInstance();
}

protected abstract T GetInstance();
}

这是您使用 Builder<T> 实现的示例.它利用嵌套类型的范围规则来访问私有(private) setter :
public class MyObject
{
private static int nextId;

protected MyObject()
{
Id = ++nextId;
}

public int Id { get; private set; }

public string Name { get; private set; }

public sealed class Builder : Builder<MyObject>
{
private MyObject _instance = new MyObject();

protected override MyObject GetInstance()
{
// Validate properties here

return _instance;
}

public string Name
{
get { return _instance.Name; }
set { _instance.Name = value; }
}
}
}

它具有到目标类型的隐式转换,允许您执行以下操作:
MyObject myObject = new MyObject.Builder { Name = "Some name" };

或这个:
public void Foo(MyObject myObject)

// ...

Foo(new MyObject.Builder { Name = "Some name" });

关于c# - 具有对象初始化器的不可变对象(immutable对象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1304154/

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