最佳实践 - 在派生类中设置的继承变量

时间:2013-04-17 11:05:26

标签: c# .net inheritance constructor abstract-class

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

我写了这个,以便在构造函数中设置变量 - 这似乎是最好的事情。但我只是觉得它有点不舒服 - 他们看起来应该是抽象属性而不是。我无法理解为什么我有这种感觉。

这是我实际完成的一个简化示例:

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)这是一个测试类,用于回归测试而不是在任何地方部署。是否有充分的理由在配置中设置我的类级别变量,或者是否可以对它们进行硬编码?我总是倾向于配置默认配置。

干杯, 马特

3 个答案:

答案 0 :(得分:4)

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

public abstract class TestBase
{
    protected string itemType;    // can now become 'readonly`

    protected TestBase(string keyName)
    {
       itemType = ConfigurationManager.AppSettings[keyName];
    }
}

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

这种方式更加一致,忘记一件物品也不那么容易。

答案 1 :(得分:1)

1:对于始终为private的字段,有很多话要说;其他访问可以工作

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";
    }
}

答案 2 :(得分:1)

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

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

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