C# 最佳实践-派生类中的继承变量集

C# 最佳实践-派生类中的继承变量集,c#,.net,inheritance,constructor,abstract-class,C#,.net,Inheritance,Constructor,Abstract Class,我有一个抽象类,其中包含依赖于类级变量的方法。但是,这些变量的值是在从抽象继承的类中设置的 我写这篇文章是为了在构造函数中设置变量——这似乎是迄今为止最整洁的事情。但我只是觉得有点不舒服——它们看起来应该是抽象属性。我就是不明白为什么我会有这种感觉 下面是我实际做过的一个简化示例: public abstract class TestBase { protected string itemType; } public class TestClass1 : TestBase {

我有一个抽象类,其中包含依赖于类级变量的方法。但是,这些变量的值是在从抽象继承的类中设置的

我写这篇文章是为了在构造函数中设置变量——这似乎是迄今为止最整洁的事情。但我只是觉得有点不舒服——它们看起来应该是抽象属性。我就是不明白为什么我会有这种感觉

下面是我实际做过的一个简化示例:

public abstract class TestBase
{
    protected string itemType;
}

public class TestClass1 : TestBase
{
    public TestClass1()
    {
        itemType = ConfigurationManager.AppSettings["TestClass1.ItemType"];
    }
}

public class TestClass2 : TestBase
{
    public TestClass2()
    {
        itemType = ConfigurationManager.AppSettings["TestClass2.ItemType"];
    }
}
因此,问题是:

1) 这是坏习惯吗

2) 如果是,为什么,还有什么更好

3) 这是一个测试类,用于回归测试,而不是部署在任何地方。是否有很好的理由像示例中那样在config中设置类级变量,或者可以硬编码它们?默认情况下,我总是倾向于配置

干杯,
Matt

您可以将数据传递给正确的构造函数:


这样做会更加一致,并且不容易忘记某个项目

1:对于总是属于
私有的
,有很多话要说;不过,其他访问也可以

2:

这里最常见的方法可能是:

public abstract class TestBase {
    private string itemType;
    protected TestBase(string itemType) {
        this.itemType = itemType;
    }
}
public class TestClass1 : TestBase {
    public TestClass1() : base(
       ConfigurationManager.AppSettings["TestClass1.ItemType"])
    {}
}
但你也可以使用:

public abstract class TestBase {
    protected string ItemType {get;set;}
    // or:
    // public string ItemType {get;protected set;}
}
public class TestClass1 : TestBase {
    public TestClass1() {
       ItemType = ConfigurationManager.AppSettings["TestClass1.ItemType"];
    }
}
如果应用程序设置名称始终与类型相关,您也可以使用一些反射:

public abstract class TestBase {
    private string itemType;
    protected TestBase() {
        itemType = ConfigurationManager.AppSettings[
            GetType().Name + ".ItemType";
    }
}

对我来说,更好的方法是声明抽象属性。若您忘记在继承的类中设置属性,那个么编译器会提醒您

public abstract class TestBase
{
    protected abstract string ItemType {get;}
}

public class TestClass1 : TestBase
{
    protected override string ItemType 
    {
        get { return ConfigurationManager.AppSettings["TestClass1.ItemType"];}
    }
}

我对您的实施感到非常满意。
public abstract class TestBase
{
    protected abstract string ItemType {get;}
}

public class TestClass1 : TestBase
{
    protected override string ItemType 
    {
        get { return ConfigurationManager.AppSettings["TestClass1.ItemType"];}
    }
}