c# - परिपत्र जेनेरिक प्रकार पैरामीटर




generics circular-dependency (2)

मेरे पास 2 सामान्य वर्ग, एक BaseComponent क्लास और एक BaseManager क्लास है।

ये दोनों सार तत्व हैं और इन्हें कंक्रीट बनाने का इरादा है

public abstract class BaseManager<T> where T : BaseComponent<?>
public abstract class BaseComponent<T> where T : BaseManager<?>

BaseManager में BaseManager की सूची है, यही वजह है कि मैं इसे सामान्य बनाना चाहता हूं, इसलिए PhysicsManager : BaseManager<PhysicsComponent> कंपनियों की एक सूची PhysicsComponents

मैं चाहता हूँ (या, मुझे लगता है कि मुझे लगता है कि) मुझे BaseComponent को सामान्य होने के लिए चाहिए क्योंकि मैं कभी भी BaseComponent से प्राप्त कक्षाओं को अपने उचित प्रबंधक को 'संलग्न' करने के लिए चाहता BaseComponent । आदर्श रूप से मैं एक व्युत्पन्न प्रति व्युत्पन्न घटक लिखना नहीं चाहता, इसलिए मैं इसे कंक्रीट प्रबंधक वर्ग में पारित करने के लिए जोड़ सकता हूं। आदर्श रूप से मैं एक ऐसा निर्माता बनाना चाहता BaseManager जो अमूर्त BaseManager क्लास लेता है।

मैं इस तरह की परिपत्र निर्भरता का प्रबंधन कैसे कर सकता हूं?


ऐसा लगता है कि आप दो सामान्य प्रकार पैरामीटर चाहते हैं:

public abstract class BaseManager<TComponent, TManager>
    where TComponent : BaseComponent<TComponent, TManager>
    where TManager : BaseManager<TComponent, TManager>
public abstract class BaseComponent<TComponent, TManager>
    where TComponent : BaseComponent<TComponent, TManager>
    where TManager : BaseManager<TComponent, TManager>

हां, यह बदबूदार है - लेकिन मैं उस प्रकार की तरह प्रोटोकॉल बफ़र्स में किया है

तो फिर आप चाहते हैं:

public class PhysicsManager : BaseManager<PhysicsComponent, PhysicsManager>

public class PhysicsComponent : BaseComponent<PhysicsComponent, PhysicsManager>

सबसे कम युग्मन होगा यदि घटकों को उनके प्रबंधकों के बारे में नहीं पता था। यहां बताया गया है कि यह कैसे काम करेगा। ध्यान दें कि इस दृष्टिकोण को किसी प्रकार की फैक्टरी तंत्र की आवश्यकता है अगर सभी घटकों को एक प्रबंधक में जोड़ा जाना चाहिए। (नट प्रैस - "यदि एक संबंध दो वस्तुओं के बीच विद्यमान है, तो किसी अन्य वस्तु को संबंध स्थापित करना चाहिए।" )

abstract class BaseComponent
{
    public event EventHandler SomethingHappened;
}

abstract class BaseManager<TComponent> where TComponent : BaseComponent
{
    List<TComponent> components = new List<TComponent>();

    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<TComponent> : 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<PhysicsComponent>, IPhysicsManager
{
    protected override void ManageMe(PhysicsComponent component)
    {
        throw new NotImplementedException();
    }

    public void AnotherCallback(PhysicsComponent comp)
    {
        throw new NotImplementedException();
    }
}

नकारात्मक पक्ष यह है कि प्रकार प्रणाली यह लागू नहीं करती है कि सही प्रबंधक को पारित किया गया है, और बेसमैनेजर में डाली तब विफल हो जाएगी मैं अभी भी इस तरह से पसंद करता हूं और अपने सभी कंक्रीट घटकों और प्रबंधकों को प्रदूषित करने के बजाय परिपत्र टेम्पलेट्स के बजाय "मेरे बुनियादी ढांचे में गंधता को बनाए रखता हूं"





circular-dependency