Fazendo uma superclasse tem uma variável estática que é diferente para cada subclasse em c #
-
12-09-2019 - |
Pergunta
Sem qualquer código no, eu gostaria de uma classe subclasses abstrato de ter uma cópia diferente de uma variável estática para cada subclasse. Em C #
abstract class ClassA
{
static string theValue;
// just to demonstrate
public string GetValue()
{
return theValue;
}
...
}
class ClassB : ClassA { }
class ClassC : ClassA { }
e (por exemplo):
(new ClassB()).GetValue(); // returns "Banana"
(new ClassC()).GetValue(); // returns "Coconut"
Minha solução atual é a seguinte:
abstract class ClassA
{
static Dictionary<Type, string> theValue;
public string GetValue()
{
return theValue[this.GetType()];
}
...
}
Enquanto esta multa funciona, eu estou querendo saber se há um mais elegante ou built-in maneira de fazer isso?
Isto é semelhante ao Can tenho cópias diferentes de uma variável estática para cada tipo diferente de herdar classe , mas eu não tenho controle sobre as subclasses
Solução
Enquanto esta multa funciona, eu estou querendo saber se há um mais elegante ou built-in maneira de fazer isso?
Não há realmente um built-in maneira de fazer isso, como você é do tipo de violar princípios básicos OO aqui. Sua classe base deve ter nenhum conhecimento de subclasses em teoria orientada a objetos tradicional.
Dito isto, se você deve fazer isso, a sua implementação é provavelmente tão boa como você está indo para obter, a menos que você pode adicionar algumas outras informações para as subclasses diretamente. Se você precisa controlar isso, e você não pode mudar subclasses, este será, provavelmente, a melhor abordagem.
Outras dicas
Existe uma maneira mais elegante. Você pode explorar o fato de que a estática em uma classe base genérico são diferentes para cada classe derivada de um 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 classe criança, o static int x será único para cada T única Deixa Derivar duas classes filhas, e nós usamos o nome da classe filho como o T genérico na classe base.
public class ChildA: BaseClass<ChildA>
{
}
public class ChildB : BaseClass<ChildB>
{
}
Agora, o MyProperty estática é único tanto para CHILDA e ChildB
ChildA TA = new ChildA();
TA.MyProperty = 8;
ChildB TB = new ChildB();
TB.MyProperty = 4;
Este é um pouco diferente do que o que você está pedindo, mas talvez realiza a mesma coisa.
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")
{
}
}
Há uma solução alternativa que pode ou não ser melhor do que a sua, dependendo do 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);
}
}
Esta abordagem é usada em EqualityComparer<T>.Default
. Claro, ele não é usado para este problema. Você realmente deve considerar fazer GetValue
abstrato e substituí-lo em cada classe derivada.
O que sobre isso?
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";
}
}
Ele funciona para mim. Seria ainda mais agradável com Interface.