gpt4 book ai didi

c# - 如何围绕 C#/Java 中缺少 const 进行设计?

转载 作者:行者123 更新时间:2023-11-30 13:24:32 25 4
gpt4 key购买 nike

在尝试为我的域建模时,我遇到了以下问题。让我们想象一下我们有一个东西:

class Thing
{
public int X { get; set; }
}

Things 有一个属性 X。然后,有 Packs,它聚合 Things。但是领域要求对包可以容纳的东西有一些限制。例如,Xes 的累积值不能高于某个特定限制:

class Pack
{
private readonly List<Thing> myThings = new List<Thing>();
private const int MaxValue = 5;

public void Add(Thing thing)
{
if (myThings.Sum(t => t.X) + thing.X > MaxValue)
throw new Exception("this thing doesn't fit here");
myThings.Add(thing);
}

public int Count
{
get { return myThings.Count; }
}

public Thing this[int index]
{
get { return myThings[index]; }
}
}

所以我在将一个东西添加到包中之前检查了条件,但仍然很容易遇到麻烦:

var pack = new Pack();
pack.Add(new Thing { X = 2 });
pack.Add(new Thing { X = 1 });

var thingOne = new Thing { X = 1 };
var thingTwo = new Thing { X = 3 };

//pack.Add(thingTwo); // exception
pack.Add(thingOne); // OK

thingOne.X = 5; // trouble
pack[0].X = 10; // more trouble

在 C++ 中,解决方案是在插入时创建一个副本并在索引器中返回 const 引用。如何在 C#(可能还有 Java)中围绕这个问题进行设计?我只是想不出一个好的解决方案:

  1. 使事物不可变 - 但如果它需要可变怎么办?
  2. 用事件/观察者观察 Pack 中的事物——但这意味着 Pack 强加了事物的设计;如果事物有更多属性怎么办?然后,由于需要 Pack 来观察变化,我将只处理一个事件 - 这对我来说似乎很尴尬。

有什么想法或首选解决方案吗?

编辑:

回到这个问题...我已经接受了 Itay 的回复。他是对的。最初的问题是,在一个上下文中,您希望 Thing 对象是不可变的,而在不同的上下文中,您希望它是可变的。这需要一个单独的界面......也许吧。我说“也许”,因为大多数时候,Pack 将是事物的集合(在 DDD 意义上),因此是对象的所有者——这意味着它不应该让您能够更改拥有的对象(或者返回副本或返回不可变接口(interface))。

很高兴在 C++ 中,const 修饰符可以如此轻松地处理这个特殊的事情。如果您想保持一致的状态,编码似乎要少得多。

最佳答案

使 Thing 不可变。

class Thing
{
public Thing (int x)
{
X = x;
}
public int X { get; private set; }
}

此外,而不是 if (myThings.Sum(t => t.X) + thing.X > MaxValue) 我认为最好在 pack 中保存一个 sum 字段,这样你就不会每次都要重新计算总和。

编辑
对不起 - 我错过了你说你需要它可变的事实。
但是...您的 C++ 解决方案将如何工作?我不太了解 C++,但 C++ 常量引用不会阻止 Pack 上实例的更改吗?

EDIT2
使用接口(interface)

public interface IThing
{
int X { get; }
}

public class Thing : IThing
{
int X { get; set; }
}

class Pack
{
private readonly List<IThing> myThings = new List<IThing>();
private const int MaxValue = 5;

public void Add(IThing thing)
{
if (myThings.Sum(t => t.X) + thing.X > MaxValue)
throw new Exception("this thing doesn't fit here");
myThings.Add(new InnerThing(thing));
}

public int Count
{
get { return myThings.Count; }
}

public IThing this[int index]
{
get { return myThings[index]; }
}

private class InnerThing : IThing
{
public InnerThing(IThing thing)
{
X = thing.X;
}
int X { get; private set; }
}
}

关于c# - 如何围绕 C#/Java 中缺少 const 进行设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3931936/

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