Hacer una superclase tiene una variable estática que es diferente para cada subclase en C #

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

Pregunta

Sin ningún tipo de código en las subclases , me gustaría una clase abstracta para tener una copia diferente de una variable estática para cada subclase. En C #

abstract class ClassA
{
    static string theValue;

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

y (por ejemplo):

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

Mi solución actual es la siguiente:

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

Aunque esto funciona bien, estoy preguntando si hay una manera más elegante o incorporada de hacer esto?

Esto es similar a heredar Puede tengo diferentes copias de una variable estática para cada tipo diferente de heredar la clase , pero no tengo ningún control sobre las subclases

¿Fue útil?

Solución

  

Aunque esto funciona bien, estoy preguntando si hay una manera más elegante o incorporada de hacer esto?

No hay realmente una forma integrada de hacer esto, ya que estás tipo de violar los principios básicos OO aquí. Su clase base no debe tener ningún conocimiento de las subclases en la teoría tradicional orientada a objetos.

Una vez dicho esto, si tiene que hacer esto, su aplicación es probablemente tan bueno como se va a conseguir, a menos que se puede añadir alguna otra información a las subclases directamente. Si necesita controlar esto, y no se puede cambiar subclases, éste será probablemente el mejor enfoque.

Otros consejos

Hay una manera más elegante. Puede explotar el hecho de que la estática en una clase base genérica son diferentes para cada clase derivada de un tipo diferente

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

Para cada clase de niño, el static int x será único para cada única T Le permite derivar dos clases hijas, y usamos el nombre de la clase del niño como el T genérica en la clase base.

public class ChildA: BaseClass<ChildA>
{
}

public class ChildB : BaseClass<ChildB>
{
}

Ahora el MyProperty estática es único tanto para Childa y Parto de

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

Esto es un poco diferente de lo que estás pidiendo, pero tal vez consigue el mismo efecto.

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

Hay una solución alternativa que podría o no podría ser mejor que el suyo, dependiendo del caso de 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);
    }
}

Este enfoque se utiliza en EqualityComparer<T>.Default. Por supuesto, no se utiliza para este problema. Que realmente debería considerar la posibilidad abstracta GetValue y anularlo en cada clase derivada.

¿Qué hay de esto?



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

A mí me funciona. Sería aún mejor con la interfaz.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top