循环generics类型参数
我有2个generics类,一个BaseComponent
类和一个BaseManager
类。
它们既抽象又有意成为具体的。
public abstract class BaseManager where T : BaseComponent public abstract class BaseComponent where T : BaseManager
BaseManager
有一个BaseComponents列表,这就是为什么我想让它成为通用的,所以PhysicsManager : BaseManager
会有一个PhysicsComponents
列表。
我想(或者更确切地说,我认为我需要) BaseComponent
是通用的,因为我只希望从BaseComponent
派生的类“附加”到它们适当的管理器。 理想情况下,我不想为每个派生组件编写构造函数,因此我可以将它添加到传递的具体管理器类中。 理想情况下,我想要一个采用抽象BaseManager
类的构造函数。
我怎样才能管理这种循环依赖?
听起来你可能想要两个generics类型参数:
public abstract class BaseManager where TComponent : BaseComponent where TManager : BaseManager public abstract class BaseComponent where TComponent : BaseComponent where TManager : BaseManager
是的,这很臭 – 但这就是我在Protocol Buffers中所做的事情。
那你就得:
public class PhysicsManager : BaseManager public class PhysicsComponent : BaseComponent
最松散的耦合是组件不知道他们的经理。 这是一个如何工作的例子。 请注意,如果必须将所有组件添加到管理器,则此方法需要某种工厂机制。 (Nat Pryce – “如果两个对象之间存在关系,那么其他一些对象应该建立关系。” )
abstract class BaseComponent { public event EventHandler SomethingHappened; } abstract class BaseManager where TComponent : BaseComponent { List components = new List (); public virtual void AddComponent(TComponent component) { components.Add(component); component.SomethingHappened += (s, e) => OnSomethingHappened(component); } public abstract void OnSomethingHappened(TComponent component); }
如果组件不能独立于其管理器,我认为它们依赖于由组件需求定义的接口会更好。 这是接口隔离原则
interface IManager { void ManageMe(BaseComponent component); } abstract class BaseComponent { public BaseComponent(IManager manager) { manager.ManageMe(this); } } abstract class BaseManager : IManager where TComponent : BaseComponent { void IManager.ManageMe(BaseComponent component) { ManageMe((TComponent)component); } protected abstract void ManageMe(TComponent component); } interface IPhysicsManager : IManager { void AnotherCallback(PhysicsComponent comp); } abstract class PhysicsComponent : BaseComponent { public PhysicsComponent(IPhysicsManager manager) : base(manager) { manager.AnotherCallback(this); } } abstract class PhysicsManager : BaseManager, IPhysicsManager { protected override void ManageMe(PhysicsComponent component) { throw new NotImplementedException(); } public void AnotherCallback(PhysicsComponent comp) { throw new NotImplementedException(); } }
缺点是类型系统不强制传入正确的管理器,然后BaseManager中的强制转换失败。 我仍然更喜欢这种方式并“在我的基础设施中保持气味”,而不是让圆形模板污染我所有的具体组件和管理人员。
上述就是C#学习教程:循环generics类型参数分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/957209.html