2009-12-03 8 views
5

Sin ningún código en las subclases, me gustaría que una clase abstracta tenga una copia diferente de una variable estática para cada subclase. En C#Hacer una superclase tiene una variable estática que es diferente 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, me pregunto si hay una manera más elegante o forma incorporada de hacer esto?

Esto es similar a Can I have different copies of a static variable for each different type of inheriting class, pero no tengo ningún control sobre las subclases

+0

Probablemente podrías hacerlo pirateando un 'Dictionary 'y llamando a' GetType() ', pero sería horrible ... –

+0

Para esos miembros estáticos virtuales/abstractos sería bueno. ver (buscar "miembro estático virtual") – VolkerK

+0

¿por qué no simplemente hacerlo NO estático? – BlackTigerX

Respuesta

5

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

En realidad, no hay una forma integrada de hacerlo, ya que estás violando los principios básicos de OO aquí. Su clase base no debería tener conocimiento de subclases en la teoría tradicional orientada a objetos.

Dicho esto, si debe hacer esto, su implementación es probablemente tan buena como la que obtendrá, a menos que pueda agregar otra información a las subclases directamente. Si necesita controlar esto, y no puede cambiar las subclases, este será probablemente su mejor enfoque.

0

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 usa para este problema. Realmente debería considerar hacer GetValue abstracto y anularlo en cada clase derivada.

+0

Mencionó que no puede anular GetValue en cada clase derivada ... – enorl76

+0

@ enorl76 Esta pregunta es muy antigua, por lo que no recuerdo el contexto real, pero no creo que este enfoque requiera reemplazar a GetValue. La última frase de mi respuesta es solo un comentario sobre el enfoque correcto, no parte de la solución. –

1

Esto es un poco diferente de lo que está pidiendo, pero quizás logra lo mismo.

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

Esa es la mejor manera obvia + - lamentablemente no puedo alterar las clases B y C – ste

1

¿Qué tal 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"; 
    } 
    } 

Funciona para mí. Sería aún mejor con Interface.

+0

Cuidado para explicar lo que está haciendo el código para el beneficio de los demás, un vertedero de código sin ninguna explicación no satisface lo que los usuarios :) – t0mm13b

+3

No, esto haría Nunca funciona. Dependiendo de cuando la máquina virtual ve los tipos, eso es cuando se llama al constructor estático, y por lo tanto 'myVariable' contendrá el valor de la última-ran-estático-constructor. Y lo que es peor, va a ser indeterminado que será la última constructor. – enorl76

Cuestiones relacionadas