Доступ к статическому свойству потомка в родительском методе - PullRequest
3 голосов
/ 10 марта 2010

Скажите, у меня есть следующий код:

class Parent
{

    static string MyField = "ParentField";

    public virtual string DoSomething()
    {
        return MyField;
    }
}

class Child : Parent
{
    static new string MyField = "ChildField";
}

Теперь я хочу сделать следующее:

Console.WriteLine(Parent.MyField);
Console.WriteLine(Child.MyField);

Эти работы, как и ожидалось, но я также хотел бы сделать это:

Child c = new Child();
Console.WriteLine(c.DoSomething());

Так как DoSomething () не определен для класса Child, возвращается MyField Родителя, но я хочу, чтобы MyField Child.

Итак, мой вопрос: есть ли способ, которым я могу это сделать?

ПРИМЕЧАНИЕ. Переопределение метода в классе Child является опцией, но, поскольку у меня будет много классов Child, наследующих от Parent, и метод должен делать то же самое во всех них, изменение чего-либо в этом методе приведет к много неприятностей.

Ответы [ 9 ]

7 голосов
/ 11 марта 2010

Если вам требуется конструкция, не поддерживаемая языком, в данном случае static virtual член - это запах, указывающий на то, что у вас может быть неисправный дизайн.

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

Другими словами, ответы, которые вы получили, не те, которые вам нужны, потому что вопрос, который вы задавали, на самом деле не тот, который вам следует задавать. Я не могу представить себе ситуацию, когда предлагаемый дизайн дает преимущества, которые не дает другой, более традиционный дизайн.

1 голос
/ 10 марта 2010

Вы должны справиться с этим и в Child:

class Child
{
    static new string MyField = "ChildField";

    public override string DoSomething()
    {
         return MyField;
    }
}

При этом использование одного виртуального свойства, вероятно, будет более понятным, поскольку вам не понадобится ключевое слово "new", чтобы скрыть поле члена Parent.

1 голос
/ 11 марта 2010

Я не понимаю, почему вы думаете, что вам нужны как «статические», так и «нестатические» среды для вызова разных свойств / функций, которые возвращают одно и то же.Если вы просто сделаете это:

class Parent
{
    public virtual string DoSomething()
    {
        return "ParentField";
    }
}

class Child
{
    public override string DoSomething()
    {
         return "ChildField";
    }
}

Тогда это будет работать так, как вы хотите:

Child c = new Child();
Console.WriteLine(c.DoSomething());

И вместо записи:

Console.WriteLine(Parent.MyField);
Console.WriteLine(Child.MyField);

вы просто напишитеthis:

Console.WriteLine(new Parent().DoSomething());
Console.WriteLine(new Child().DoSomething());

Есть ли какие-то другие ограничения на проблему, которые делают это неприемлемым?Например, создание новых объектов этих классов чрезвычайно дорого по некоторым причинам?

0 голосов
/ 11 марта 2010

Во-первых, позвольте мне сказать, что вы действительно должны просто сделать MyField виртуальным и признать, что вам нужно создать экземпляр для его получения. Тем не менее, другой способ «решения» проблемы будет:

class Parent
{
    public static string MyField = "ParentField";
    protected virtual MyLocalField = MyField;

    public virtual string DoSomething()
    {
        return MyLocalField;
    }
}
class Child : Parent
{
    public static new string MyField = "ChildField";
    protected override MyLocalField = MyField;
}
0 голосов
/ 10 марта 2010

Единственный способ - переопределить метод DoSomething, иначе это невозможно. Метод DoSomething in Parent, по сути, означает:

public virtual string DoSomething()
    {
        return Parent.MyField;
    }

Когда вы "new" свойство, оно применяется только к этому типу - в данном случае Child класс. Если свойство доступно через 'Parent', оно всегда будет возвращать исходное свойство.

0 голосов
/ 10 марта 2010

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

class Parent
{
    protected virtual string MyField() { return "ParentField"; }

    public virtual string DoSomething()
    {
        return MyField();
    }
}

class Child : Parent
{
    protected override string MyField() { return "ChildField"; }
} 
0 голосов
/ 10 марта 2010

Никакой магии наследования нет ничего статичного, но вы можете сделать это

protected virtual string { get { return "your value"; } }

и используйте свойство внутри вашего метода

0 голосов
/ 10 марта 2010

Да, переопределить DoSomething:

class Child
{
    static new string MyField = "ChildField";

    public virtual string DoSomething()
    {
        return MyField;
    }

}
0 голосов
/ 10 марта 2010

Используйте статическое свойство вместо статической переменной. Затем вы можете переопределить свойство в дочернем классе вместо создания «нового» поля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...