I’m trying to teach myself about OOP in C#, but I have a question about when to use base. I understand the general principles, but I’m not sure what’s best in the example below. This simple test includes:
- An
interfacewith twostringproperties - An
abstractclass that implements this interface and adds a couple morestringproperties - Two classes that implement the abstract class. One uses
baseand the other doesn’t, but they both produce the same output when the program is executed.
My question is: in this example, is one implementation more desirable than the other? I’m not really sure if there are any meaningful differences between TranslationStyleA and TranslationStyleB, or if it’s just down to personal preference?
Many thanks for your time and thoughts!
using System;
namespace Test
{
interface ITranslation
{
string English { get; set; }
string French { get; set; }
}
public abstract class Translation : ITranslation
{
public virtual string English { get; set; }
public virtual string French { get; set; }
public string EnglishToFrench { get { return English + " is " + French + " in French"; } }
public string FrenchToEnglish { get { return French + " is " + English + " in English"; } }
public Translation(string e, string f)
{
English = e;
French = f;
}
}
public class TranslationStyleA : Translation
{
public override string English
{
get { return base.English; }
set { base.English = value; }
}
public override string French
{
get { return base.French; }
set { base.French = value; }
}
public TranslationStyleA(string e, string f) : base(e, f)
{
}
}
public class TranslationStyleB : Translation
{
private string english;
public override string English
{
get { return english; }
set { english = value; }
}
private string french;
public override string French
{
get { return french; }
set { french = value; }
}
public TranslationStyleB(string e, string f) : base(e, f)
{
this.English = e;
this.French = f;
}
}
class Program
{
static void Main(string[] args)
{
TranslationStyleA a = new TranslationStyleA("cheese", "fromage");
Console.WriteLine("Test A:");
Console.WriteLine(a.EnglishToFrench);
Console.WriteLine(a.FrenchToEnglish);
TranslationStyleB b = new TranslationStyleB("cheese", "fromage");
Console.WriteLine("Test B:");
Console.WriteLine(b.EnglishToFrench);
Console.WriteLine(b.FrenchToEnglish);
Console.ReadKey();
}
}
}
The first thing that you need to understand is what’s going on when you have an automatic property:
Behind the scenes, the compiler is generating a private field, and getting/setting that private field when you access the property. It is equivalent to this
except that you don’t know the name of the private field, and so you cannot access it.
So in your
TranslationStyleAclass, you are not actually doing anything with the English property, because it just accesses the base class’s property directly and doesn’t change it’s behavior.Now in the
TranslationStyleBclass, you are actually changing the behavior of the property (albeit in a fairly useless way). Instead of storing the value for the English property in the base class’s auto-implemented private variable, you are storing it in the private variable defined at the derived class level:Neither of these implementations does anything of course, and as implemented neither is needed, since the base class implements the properties perfectly fine itself. So my answer to your original question is that neither is preferred, given the code as you describe it.
Now, let’s look at an example where your question is relevant. You only need to override them if you want to change their behavior, for instance.
We want to delegate to the base class here, because of why these were properties in the first place. Semantically, a property is the same as a field:
The reason is that from the compiler’s perspective, it is a breaking change in an interface to go from a property to a field. So if I change
to
Then any code that depends on my code needs to be recompiled. However, if I change
to
then dependent code still only sees the public property, and does not need recompilation (because the interface of my class has not changed).
If the base class here (
Translation) were to change it’s behavior for the propertyEnglishthus:the you would want to pick that up in your derived classes!
So considering that properties have behavior associated with them, you should always delegate to the parent class implementation unless that implementation has undesirable effects in your deriving class.