OOP基础:从派生类在base-ctor中创建重写对象

时间:2013-01-10 16:32:58

标签: c# oop

抱歉标题不好,但我的英语不太好 假设以下代码(在程序模式下使用LINQPad进行测试):

public class BaseClass
{
    protected Settings settings;

    public BaseClass()
    {
        this.settings = new Settings();
    }

    public virtual void PrintSettings()
    {
        var t = settings.GetType();
        Console.WriteLine(string.Join(", ", t.GetProperties().Select(pi => pi.Name)));
    }

    public class Settings
    {
        public string BaseClassSetting { get { return "BaseClassSetting."; } }
    }
}

调用“new BaseClass()。PrintSettings();”显然会在Console中输出“BaseClassSetting” 让我们从BaseClass派生出一个类:

public class InheritedClass : BaseClass
{
    public new class Settings : BaseClass.Settings
    {
        public string InheritedClassSetting { get { return "InheritedClassSetting!"; } }
    }
}

调用“new InheritedClass()。PrintSettings();”仍会在Console中打印“BaseClassSetting” 使代码使用“new”ed InheritedClass.Settings的唯一方法是添加像

这样的ctor。
public InheritedClass()
{
    this.settings = new Settings();
}

使用这个附加的ctor,它会将所需的“InheritedClassSetting,BaseClassSetting”输出到控制台。
现在的问题是:是否可以使BaseClass-ctor始终使用实例对象的Settings-Class? (不在派生类中添加ctor)

2 个答案:

答案 0 :(得分:1)

对于不良做法,预计会遇到问题的不良解决方法。我不会一般使用new关键字,更不用说嵌套类了。您可以通过使基类接受继承自BaseClass.Settings和无参数构造函数的泛型类型来删除继承类中的构造函数。显然,这是不可读的。

public class BaseClass<T> where T : BaseClass<T>.Settings, new()
{
    protected Settings settings;

    public BaseClass()
    {
        settings = new T();
    }

    public virtual void PrintSettings()
    {
        var t = settings.GetType();
        Console.WriteLine(string.Join(", ", t.GetProperties().Select(pi => pi.Name)));
    }

    public class Settings
    {
        public string BaseClassSetting
        {
            get { return "BaseClassSetting."; }
        }
    }
}

public class InheritedClass : BaseClass<InheritedClass.Settings>
{
    public new class Settings : BaseClass<InheritedClass.Settings>.Settings
    {
        public string InheritedClassSetting
        {
            get { return "InheritedClassSetting!"; }
        }
    }
}

请注意:

public new class Settings : BaseClass<InheritedClass.Settings>.Settings

泛型的参数不需要您指定InheritedClass。我添加它因为它已经非常令人困惑,我不想让它变得更糟。

答案 1 :(得分:1)

不,因为你不能拥有“虚拟类型”。

有几种方法可以尝试实现您在此处所做的工作,但所有这些方法都需要InheritedClass在某些时候明确引用自己的Settings版本。

相关问题