如何在基类上使用派生属性?

you*_*pal 0 c# inheritance

我有一个基类,它有一个属性和一个使用该属性的方法.我有一个继承该基类的类,并且有自己的基类属性实现,使用New修饰符显式隐藏.在基类的方法中,是否有一种使用继承类'属性而不是基类实现的好方法?

class Program
{
    public class MyBase
    {
        public string MyProperty { get { return "Base"; } }

        public string MyBaseMethod()
        {
            return MyProperty;
        }
    }

    public class MyInherited : MyBase
    {
        public new string MyProperty { get { return "Inherited"; } }
    }

    static void Main(string[] args)
    {
        List<MyBase> test = new List<MyBase>();
        test.Add(new MyBase());
        test.Add(new MyInherited());

        foreach (MyBase item in test)
        {
            Console.WriteLine(item.MyBaseMethod());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在示例中,输出为:Base Base

目前的解决方法:

    ...
    public class MyBase
    {
        public string MyProperty { get { return "Base"; } }
        public string MyBaseMethod()
        {
            if (this is MyInherited)
            {
                return baseMethod(((MyInherited)this).MyProperty);
            }
            else
            {
                return baseMethod(MyProperty);
            }
        }

        private string baseMethod(string input)
        {
            return input;
        }
    }
    ...
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?我宁愿不必做明确的类型转换.

Oli*_*bes 5

new通常应避免使用关键字隐藏成员.而是创建基类'属性virtual并在降序类中覆盖它.MyBaseMethod在继承类时,它将自动使用此重写属性.

public class MyBase
{
    public virtual string MyProperty { get { return "Base"; } }

    public string MyBaseMethod()
    {
        return MyProperty;
    }
}

public class MyInherited : MyBase
{
    public override string MyProperty { get { return "Inherited"; } }
}
Run Code Online (Sandbox Code Playgroud)
var inherited = new MyInherited();
Console.WriteLine(inherited.MyBaseMethod()); // ==> "Inherited"
Run Code Online (Sandbox Code Playgroud)

看到这个与new关键字相关的有趣帖子:为什么我们需要new关键字?为什么默认行为要隐藏而不是覆盖?