如果您有 Martin Fowler 的重构书,只需按照“将单向关联更改为双向”重构即可。
如果您没有它,以下是重构后您的类的外观:
class C
{
// Don't to expose this publicly so that
// no one can get behind your back and change
// anything
private List<W> contentsW;
public void Add(W theW)
{
theW.Container = this;
}
public void Remove(W theW)
{
theW.Container = null;
}
#region Only to be used by W
internal void RemoveW(W theW)
{
// do nothing if C does not contain W
if (!contentsW.Contains(theW))
return; // or throw an exception if you consider this illegal
contentsW.Remove(theW);
}
internal void AddW(W theW)
{
if (!contentW.Contains(theW))
contentsW.Add(theW);
}
#endregion
}
class W
{
private C containerC;
public Container Container
{
get { return containerC; }
set
{
if (containerC != null)
containerC.RemoveW(this);
containerC = value;
if (containerC != null)
containerC.AddW(this);
}
}
}
请注意,我已将其List<W>
设为私有。通过枚举器公开 Ws 列表,而不是直接公开列表。
例如 public List GetWs() { return this.ContentW.ToList(); }
上面的代码正确地处理了所有权的转移。假设您有两个 C 实例——C1 和 C2——以及 W 的实例——W1 和 W2。
W1.Container = C1;
W2.Container = C2;
在上面的代码中,C1 包含 W1,C2 包含 W2。如果将 W2 重新分配给 C1
W2.Container = C1;
然后 C2 将有零个项目,C1 将有两个项目 - W1 和 W2。你可以有一个浮动的W
W2.Container = null;
在这种情况下,W2 将从 C1 的列表中删除,并且它没有容器。您还可以使用 C 中的 Add 和 Remove 方法来操作 W 的容器 - 因此 C1.Add(W2) 将自动从其原始容器中删除 W2 并将其添加到新容器中。