当前位置: 首页 > 编程语言 > C#

对于需要引用其他类的类,C#中好的设计模式是什么?分享

时间:2023-04-10 12:59:41 C#

C#中对于需要引用其他类的类,什么是好的设计模式?我正在处理C#.NET中的业务问题。我有两个名为C和W的类,它们将在不同时间独立实例化。一个C类对象需要包含0...n个W类对象的引用,即一个C对象最多可以包含n个W对象。每个W对象需要包含对类C的1个对象的引用,即W对象包含在C对象中。通常首先实例化类C的对象。稍后,将发现并实例化其W内容。在此之后,我需要将C和W对象相互交叉引用。什么是好的设计模式?我实际上有一些案例,我有三个或四个类,但我们可以讨论两个类以保持简单。我在想一些简单的事情:classC{publicListcontentsW;}类W{公共CcontainerC;这暂时可行,但我可以预见必须编写大量代码来跟踪所有引用及其有效性。我想实现后面的代码,只对容器进行浅刷新,对所有引用的类进行深度刷新。还有其他方法吗?它们的优点是什么?编辑11/3:感谢大家的精彩回答和精彩讨论。我最终选择了乔普的回答,因为它最接近我想要的,但其他答案也有帮助。再次感谢!如果您有MartinFowler的重构书,请遵循“将单向关联更改为双向”重构。如果你没有它,那么重构后你的类看起来像这样:publicvoidAdd(WtheW){theW.Container=this;}publicvoidRemove(WtheW){theW.Container=null;}#regionOnlytobeusedbyWinternalvoidRemoveW(WtheW){//如果C不包含W,则什么也不做if(!contentsW.Contains(theW))return;//如果您认为这是非法内容,则抛出异常W.Remove(theW);}internalvoidAddW(WtheW){if(!contentW.Contains(theW))contentsW.Add(theW);}#endregion}classW{privateCcontainerC;publicContainerContainer{get{returncontainerC;}set{if(containerC!=null)containerC.RemoveW(this);容器C=值;如果(containerC!=null)containerC.AddW(this);}}}请注意,我已将列表设为私有。通过枚举器公开Ws列表,而不是直接公开列表。例如publicListGetWs(){returnthis.ContentW.ToList();上面的代码正确地处理了所有权的转移。假设您有两个C实例-C1和C2-和W-W1和W2实例。W1.容器=C1;W2.容器=C2;在上面的代码中,C1包含W1,C2包含W2。如果将W2重新分配给C1W2.Container=C1;那么C2将有零个项目,C1将有两个项目-W1和W2。你可以有一个浮动的W.W2.Container=null;在这种情况下,W2将从C1的列表中删除,并且它将没有容器。您还可以使用C中的Add和Remove方法来操作W的容器-因此C1.Add(W2)将自动从其原始容器中删除W2并将其添加到新容器中。我通常这样做:classC{privateList_contents=newList();publicIEnumerableContents{get{return_contents;}}publicvoidAdd(Witem){item.C=this;_contents.Add(项目);所以你的Contents属性是只读的,你只能通过聚合方法添加项目。好吧,看起来你差不多明白了,有一个小故障——你必须能够控制C中列表的添加。例如,classC{privateList_contentsW;公共列表内容{get{return_contentsw;}}publicvoidAddToContents(W内容);{content.Container=这个;_contentsW.Add(内容);要检查,你只需要迭代你的列表,我认为:foreach(varwin_contentsW){if(w.Container!=this){w.Container=this;不确定这是否是您需要的。请注意,可能有多个W实例具有相同的值,但可能有不同的C容器。扩展Jons的答案....如果W不应该让C保持活动状态,则可能需要弱引用。另外......如果你想转移所有权,添加应该更复杂......publicvoidAddToContents(Wcontent);{if(content.Container!=null)content.Container.RemoveFromContents(content);content.Container=这个;_contentsW.Add(内容);}一种选择是在System.ComponentModel下实现IContainer和IComponent接口。C是容器,W是组件。然后ComponentCollection类将用作W实例的存储,IComponent.Site将提供到C的反向链接。这就是我使用的模式。}publicIListChildren{get{returnChildrenBidi;}set{ChildrenBidi.Set(value);}}privateBidiChildListChildrenBidi{get{returnBidiChildList.Create(this,p=>p._Children,c=>c._Parent,(c,p)=>c._Parent=p);}}内部IList_Children=newList();}publicclassChild{publicstringName{get;放;}publicParentParent{get{returnParentBidi.Get();}set{ParentBidi.Set(value);}}privateBidiParentParentBidi{get{returnBidiParent.Create(this,p=>p._Children,()=>_Parent,p=>_Parent=p);}}内部父级_Parent=null;显然,我有类BidiParent和BidiChildList,它们实现了IList等。幕后更新是通过内部字段完成的,而使用此域模型的代码的更新是通过公共属性完成的。以上就是C#学习教程:对于需要引用其他类的类,C#中好的设计模式是什么?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: