4

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

我写了这个,以便在构造函数中设置变量 - 这似乎是迄今为止最巧妙的事情。但我只是觉得有点不舒服——它们看起来应该是抽象的属性。我只是无法说出我为什么会有这种感觉。

这是我实际所做的简化示例:

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 中设置我的类级变量,或者可以对它们进行硬编码?我总是倾向于默认配置。

干杯,马特

4

3 回答 3

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

这样一来,它更加一致并且不容易忘记一个项目。

于 2013-04-17T11:10:48.847 回答
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";
    }
}
于 2013-04-17T11:10:52.510 回答
1

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

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

public class TestClass1 : TestBase
{
    protected override string ItemType 
    {
        get { return ConfigurationManager.AppSettings["TestClass1.ItemType"];}
    }
}
于 2013-04-17T11:18:24.080 回答