سؤال

دون أي رمز في الفئات الفرعية, ، أود الحصول على فئة مجردة للحصول على نسخة مختلفة من متغير ثابت لكل فرعية. في ج #

abstract class ClassA
{
    static string theValue;

    // just to demonstrate
    public string GetValue()
    {
        return theValue;
    }
    ...
}
class ClassB : ClassA { }
class ClassC : ClassA { }

و (على سبيل المثال):

(new ClassB()).GetValue(); // returns "Banana"
(new ClassC()).GetValue(); // returns "Coconut"

الحل الحالي هو:

abstract class ClassA
{
    static Dictionary<Type, string> theValue;
    public string GetValue()
    {
        return theValue[this.GetType()];
    }
    ...
}

في حين أن هذا يعمل بشكل جيد، أتساءل عما إذا كان هناك طريقة أكثر أناقة أو مدمجة للقيام بذلك؟

هذا يشبه هل يمكنني الحصول على نسخ مختلفة من متغير ثابت لكل نوع مختلف من فئة الوراء, ، لكن ليس لدي سيطرة على الفئات الفرعية

هل كانت مفيدة؟

المحلول

في حين أن هذا يعمل بشكل جيد، أتساءل عما إذا كان هناك طريقة أكثر أناقة أو مدمجة للقيام بذلك؟

لا توجد حقا طريقة مدمجة للقيام بذلك، لأنك تنتهك مبادئ OO الأساسية هنا. يجب أن يكون للفئة الأساسية الخاصة بك أي معرفة فرعية في النظرية الموجهة نحو الكائنات التقليدية.

ومع ذلك، إذا كان يجب عليك القيام بذلك، فربما يكون تنفيذك جيدا كما ستحصل عليه، إلا إذا كان بإمكانك إضافة بعض المعلومات الأخرى إلى الفئات الفرعية مباشرة. إذا كنت بحاجة إلى التحكم في هذا، ولا يمكنك تغيير الفئات الفرعية، فمن المحتمل أن يكون هذا أفضل طريقة لك.

نصائح أخرى

هناك طريقة أكثر أناقة. يمكنك استغلال حقيقة أن الإحصاء في فئة قاعدة عامة مختلفة مختلفة عن كل فئة مشتقة من نوع مختلف

public abstract class BaseClass<T> where T : class
{
    public static int x = 6;
    public int MyProperty { get { return x; } set { x = value; } }
}

بالنسبة لكل فئة طفل، ستكون STATIC INT X فريدة لكل فريدة من نوعها، مما يتيح أن تستمد طبقي طفيفين، ونحن نستخدم اسم فئة الطفل كعهد ر في الفئة الأساسية.

public class ChildA: BaseClass<ChildA>
{
}

public class ChildB : BaseClass<ChildB>
{
}

الآن MyProperty ثابتة فريدة من نوعها لكل من الأطفال والطول

        ChildA TA = new ChildA();
        TA.MyProperty = 8;
        ChildB TB = new ChildB();
        TB.MyProperty = 4;

هذا يختلف قليلا عن ما تطلبه، ولكن ربما ينجز نفس الشيء.

    class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine((new B()).theValue);
        Console.WriteLine((new C()).theValue);
        Console.ReadKey();
    }
}

public abstract class A
{
    public readonly string theValue;

    protected A(string s)
    {
        theValue = s;
    }
}

public class B : A
{
    public B(): base("Banana")
    {
    }
}

public class C : A
{
    public C(): base("Coconut")
    {
    }
}

هناك حل بديل قد يكون أو لا يكون أفضل من لك، اعتمادا على حالة الاستخدام:

abstract class ClassA
{
    private static class InternalClass<T> {
        public static string Value;
    }
    public string GetValue()
    {
        return (string)typeof(InternalClass<>)
              .MakeGenericType(GetType())
              .GetField("Value", BindingFlags.Public | BindingFlags.Static)
              .GetValue(null);
    }
}

يستخدم هذا النهج في EqualityComparer<T>.Default. وبعد بالطبع، لا يستخدم لهذه المشكلة. يجب عليك حقا النظر في صنع GetValue مجردة وتجاوزه في كل فئة مشتقة.

ماذا عن هذا؟



    class Base {
    protected static SomeObjectType myVariable;

    protected void doSomething()
    {
    Console.WriteLine( myVariable.SomeProperty );
    }
    }

    class AAA : Base
    {
    static AAA()
    {
    myVariable = new SomeObjectType();
    myVariable.SomeProperty = "A";
    }
    }

    class BBB : Base
    {
    static BBB()
    {
    myVariable = new SomeObjectType();
    myVariable.SomeProperty = "B";
    }
    }

انه يعمل بالنسبة لي. سيكون حتى أجمل مع واجهة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top