Как переопределить, а не скрыть переменную-член (поле) в подклассе C #? - PullRequest
24 голосов
/ 13 января 2012

Я хочу, чтобы это сообщило мне Имя как ItemA, так и ItemB.Он должен сказать мне «Subitem \ nSubitem», но вместо этого он говорит мне «Item \ nSubitem».Это связано с тем, что переменная «Имя», определенная в классе Subitem, технически является переменной, отличной от переменной «Имя», определенной в базовом классе Item.Я хочу изменить исходную переменную на новое значение.Я не понимаю, почему это не самая легкая вещь, учитывая виртуальную и переопределенную работу с методами.Мне совершенно не удалось выяснить, как на самом деле переопределить переменную.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Console.WriteLine(ItemA.Name);
            System.Console.WriteLine(ItemB.Name);
            System.Console.ReadKey();
        }
        static Item ItemA = new Subitem();
        static Subitem ItemB = new Subitem();
    }
    public class Item
    {
        public string Name = "Item";
    }
    public class Subitem : Item
    {
        new public string Name = "Subitem";
    }
}

Ответы [ 5 ]

34 голосов
/ 13 января 2012

Вы не можете переопределить переменные в C #, но вы можете переопределить свойства:

public class Item
{
    public virtual string Name {get; protected set;}
}
public class Subitem : Item
{
    public override string Name {get; protected set;}
}

Другой подход заключается в изменении значения в подклассе, например:

public class Item
{
    public string Name = "Item";
}
public class Subitem : Item
{
    public Subitem()
    {
        Name = "Subitem";
    }
}
8 голосов
/ 13 января 2012

Не существует понятия полиморфизма (что заставляет override делать свое дело) с полями (что вы называете переменными).Вместо этого вам нужно использовать свойство.

public class Item
{
    public virtual string Name
    {
        get { return "Item"; }
    }
}

public class SubItem : Item
{
    public override string Name
    {
        get { return "Subitem"; }
    }
}
5 голосов
/ 13 января 2012

Что будет означать «переопределение переменной»?

Переменная - это именованная ячейка в концептуальной памяти («концептуальная», потому что она может быть регистром, хотя с полями это маловероятно).

Переопределение метода заменяет один набор операций другим.

Поскольку именованное место в памяти не является набором операций, как вы можете его заменить? Что должны делать эти именованные места в памяти?

Если вы хотите изменить то, что хранится в памяти, просто сделайте это при создании производного класса:

public class Item
{
  public string Name = "Item";
}
public class Subitem : Item
{
  public SubItem()
  {
    Name = "Subitem";
  }
}

Если вы хотите переопределить как набор операций, определите набор операций (метод или свойство) для переопределения.

2 голосов
/ 13 августа 2017

Этот вопрос относительно старый, и автор, вероятно, использовал C # 5.0 или ниже. Но у меня возник тот же вопрос, и я нашел очень аккуратное решение, которое работает с C # 6.0 и выше, которым я хочу поделиться с вами:

C # 6.0 дает возможность инициализировать авто-свойства. Так что можно использовать только это:

public class Item
{
    public virtual string Name { get; set; } = "Item";
}

public class Subitem : Item
{
    public override string Name { get; set; } = "Subitem";
}
0 голосов
/ 13 января 2012

Возможным решением будет использование свойства и переопределение его getter , например, так:

public class Item
{
    public virtual string Name { get { return "Item"; } }
}
public class Subitem : Item
{
    public override string Name { get { return "Subitem"; } }
}
...