Best practice - inherited variables set in derived classes

I have an abstract class containing methods that rely on class variables. However, the values โ€‹โ€‹of these variables are set in classes that inherit from the abstract.

I wrote this so that the variables were set in the constructor - it seemed like this was the hardest thing. But I just feel uncomfortable with this - they look like they should be abstract properties. I just can't say why I feel this way.

Here is a simplified example of what I actually did:

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

So the questions are:

1) Is this bad practice?

2) If so, why and what is better?

3) This is a test class used for regression testing, and not for deployment anywhere. Is there a good reason to set variables at the class level in config, as in the example, or is it good to hardcode them? I am by default always configured.

Cheers, Matt

+4
source share
3 answers

You can pass data to the right constructor (s):

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

Thus, it is more consistent and not so easy to forget the subject.

+4
source

1: much can be said that fields are always private ; other access may work.

2:

The most common approach here is probably:

 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"]) {} } 

but you can also just use:

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

If the application name is always of type, you can also use some reflection:

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

For me, the best way is to declare an abstract property. If you forget to set the property in an inherited class, then the compiler will remind you.

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

All Articles