0

抱歉标题不好,但我的英语不是那么好。
假设以下代码(在程序模式下使用 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();” 显然会在控制台中输出“BaseClassSetting”。
让我们从 BaseClass 派生一个类:

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

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

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

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

4

2 回答 2

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. 我已经添加了它,因为它已经很混乱了,我不想让它变得更糟。

于 2013-01-10T16:39:14.840 回答
1

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

您可以通过多种方式尝试实现您在此处所做的事情,但所有这些方式都需要在某个时候InheritedClass明确引用其自己的版本。Settings

于 2013-01-10T16:41:00.463 回答