Fare una superclasse hanno una variabile statica che è diverso per ogni sottoclasse in C #

StackOverflow https://stackoverflow.com/questions/1843114

Domanda

senza alcun codice nelle sottoclassi , mi piacerebbe una classe astratta di avere una copia diversa di una variabile statica per ogni sottoclasse. In C #

abstract class ClassA
{
    static string theValue;

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

e (per esempio):

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

La mia soluzione attuale è questa:

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

Anche se questo funziona bene, mi chiedo se c'è un modo più elegante o built-in di fare questo?

Questo è simile a ereditare Can ho diverse copie di una variabile statica per ogni diverso tipo di ereditare classe , ma non ho alcun controllo su sottoclassi

È stato utile?

Soluzione

  

Anche se questo funziona bene, mi chiedo se c'è un modo più elegante o built-in di fare questo?

non c'è davvero un modo integrato di fare questo, come si sta sorta di violazione dei principi di base OO qui. La classe di base dovrebbe avere alcuna conoscenza delle sottoclassi in teoria tradizionale orientato agli oggetti.

Detto questo, se si deve fare questo, l'implementazione è probabilmente circa buono come si sta andando ad ottenere, a meno che non è possibile aggiungere alcune altre informazioni per le sottoclassi direttamente. Se avete bisogno di controllare questo, e non è possibile modificare sottoclassi, questo sarà probabilmente il vostro approccio migliore.

Altri suggerimenti

C'è un modo più elegante. È possibile sfruttare il fatto che statica in una classe base generica sono diversi per ogni classe derivata di tipo diverso

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

Per ogni classe figlia, int x statica sarà unica per ogni unica T Permette di ricavare due classi figlie, e usiamo il nome della classe del bambino come il T generica nella classe base.

public class ChildA: BaseClass<ChildA>
{
}

public class ChildB : BaseClass<ChildB>
{
}

Ora la MyProperty statica è unico sia per Childa e ChildB

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

Questo è un po 'diverso da quello che stai chiedendo, ma forse compie la stessa cosa.

    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")
    {
    }
}

C'è una soluzione alternativa che potrebbe o non potrebbe essere migliore della tua, a seconda del caso d'uso:

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);
    }
}

Questo approccio viene utilizzato in EqualityComparer<T>.Default. Naturalmente, non è usato per questo problema. Si dovrebbe considerare la possibilità di GetValue astratta e sovrascrivere in ogni classe derivata.

Che dire di questo?



    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";
    }
    }

Funziona per me. Sarebbe ancora più bello con l'interfaccia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top