我有一个抽象类,包含依赖于类级变量的方法。但是,这些变量的值是在从抽象继承的类中设置的。
我写了这个,以便在构造函数中设置变量 - 这似乎是最好的事情。但我只是觉得它有点不舒服 - 他们看起来应该是抽象属性而不是。我无法理解为什么我有这种感觉。
这是我实际完成的一个简化示例:
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)这是一个测试类,用于回归测试而不是在任何地方部署。是否有充分的理由在配置中设置我的类级别变量,或者是否可以对它们进行硬编码?我总是倾向于配置默认配置。
干杯, 马特
答案 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"];}
}
}