Создание в суперклассе статической переменной, которая отличается для каждого подкласса в c#

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

Вопрос

Без какого-либо кода в подклассах, Я бы хотел, чтобы абстрактный класс имел другую копию статической переменной для каждого подкласса.В C#

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()];
    }
    ...
}

Хотя это работает нормально, мне интересно, есть ли более элегантный или встроенный способ сделать это?

Это похоже на Могу ли я иметь разные копии статической переменной для каждого отдельного типа наследуемого класса, но у меня нет контроля над подклассами

Это было полезно?

Решение

Хотя это работает нормально, мне интересно, есть ли более элегантный или встроенный способ сделать это?

На самом деле не существует встроенного способа сделать это, поскольку здесь вы как бы нарушаете основные принципы объектно-ориентированного программирования.Ваш базовый класс не должен знать подклассов традиционной объектно-ориентированной теории.

При этом, если вам необходимо это сделать, ваша реализация, вероятно, будет настолько хороша, насколько вы сможете получить, если только вы не сможете напрямую добавить другую информацию в подклассы.Если вам нужно это контролировать и вы не можете менять подклассы, это, вероятно, будет вашим лучшим подходом.

Другие советы

Есть более элегантный способ.Вы можете использовать тот факт, что статика в универсальном базовом классе различна для каждого производного класса другого типа

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

Для каждого дочернего класса статический int x будет уникальным для каждого уникального T Давайте создадим два дочерних класса, и мы будем использовать имя дочернего класса в качестве универсального T в базовом классе.

public class ChildA: BaseClass<ChildA>
{
}

public class ChildB : BaseClass<ChildB>
{
}

Теперь статическое свойство MyProperty уникально как для Childda, так и для ChildB

        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