Unsure when to use 'base' in C# - c#

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 interface with two string properties
An abstract class that implements this interface and adds a couple more string properties
Two classes that implement the abstract class. One uses base and 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:
public virtual string English { get; set; }
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
private string _english;
public virtual string English { get { return _english; } set { _english = value; } }
except that you don't know the name of the private field, and so you cannot access it.
So in your TranslationStyleA class, 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.
// None of this is even needed- we are just delegating to the base class
public override string English
{
get { return base.English; }
set { base.English = value; }
}
Now in the TranslationStyleB class, 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:
private string english;
public override string English
{
get { return english; }
set { english = value; }
}
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 don't want any leading or trailing whitespace, so we remove it here.
public override string English
{
get { return base.English; }
set { base.English = value.Trim(); }
}
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:
public String Foo;
public String Foo { get; set; } // <-- why bother with all this extra { get; set; } stuff?
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
public String Foo;
to
public String Foo { get; set; }
Then any code that depends on my code needs to be recompiled. However, if I change
public String Foo { get; set; }
to
private string _foo;
public String Foo { get { return _foo; } set { _foo = value.Trim(); } }
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 property English thus:
private string _english;
public String English { get { return _english; } set { _english = value.ToUpper(); } }
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.

The first style is definitely preferable unless you have some good reason to pick the other one.
The automatically-implemented properties of Translation each add a field, and style B adds more rather than using the ones the compiler added. Style A reuses the one the compiler added, saving some storage.
Additionally, there's no need to override the superclass's properties if you're not going to change their functionality. You could even write another style like this:
public class TranslationStyleC : Translation {
public TranslationStyleC(string e, string f) : base(e, f) {
}
}

You don't really need to override any of the superclass properties to achieve the effect that you intend, since you don't enhance the superclass behavior in any way.
If you remove the abstract modifier from the base Translation, you don't need the subclasses anymore, since it will be functionally equivalent to both.
Now, as to when to use base; you should use it when you want to access functionality in the superclass that's been overridden in the subclass. base calls are always statically bound to the superclass method at compile time; even if the superclass method is virtual (as in your case). For a curious thing that can happen with base calls take a look here.

As mentioned before, style A reuses the fields already declared whereas style B declares new fields. Regarding your question about when to use base, the rule of thumb would be "whenever you would like to reuse logic/code defined in the parent class".

It does come down to how you intend to leverage your constructs.
As implemented, the overridden members on TranslationStyleA are a bit redundant as the consumer could just as easily access the base members without providing the overrides in the base derivation. In cases such as these I personally won't bother overriding the base members at all if doing so doesn't add any value to design.
The second implementation is common when you truly want to override the setting and accessing of base class members, for instance, if the setting of a base class member is the catalyst for initiating another operation then the overriden member on the derivation would be an appropriate place for that to occur.

Related

Inheritance variables in c#

Just for practice I'm trying to write a calculator program. To make it difficult I trying to use some of the advanced inheritance topics I've learned, but not really used. Lets say you have an interface named IMath with one method string DoMath(). Is it possible to have a variable written in the IMath interface that all classes implementing that interface would see new values? So for example my class Add : IMath would have the method DoMath() and in that DoMath() method would change the value of the variable double ITotal which all classes that implement the IMath interface would see the new value.
You cannot specify variables or fields in interfaces, you can only specify:
Methods
Properties
Indexers
Events
See the C# documentation on interfaces for more information about this.
An interface dictates expected behavior, it does not dictate expected implementation. A property can be read as "the ability to retrieve the value of X" or "the ability to provide the value of X", where as a variable is "the ability to store X". This is not the same thing, and interfaces cannot make that guarantee.
If you absolutely need to enforce the presence of a variable, you should use a base class. I would probably look into combining these things, use interfaces for the external interface (ie. how should my calculator function) and base class and inheritance to avoid rewriting the same code over and over.
It sounds like what you're looking for is an abstract base class.
One possible implementation of what you describe is shown below.
public abstract class MathBase
{
public double Total { get; protected set; }
public abstract string DoMath(double value);
protected double ParseValue(string value)
{
double parsedValue;
if (!double.TryParse(value, out parsedValue))
{
throw new ArgumentException(string.Format("The value '{0}' is not a number.", value), "value");
}
return parsedValue;
}
}
public class Add : MathBase
{
public override string DoMath(string value)
{
Total += ParseValue(value);
return Convert.ToString(Total);
}
}
If you wanted every instance of every class that inherits from MathBase to share the same Total value, you would declare it as static:
public abstract class MathBase
{
public static double Total { get; protected set; }
public abstract string DoMath(string value);
}
(although I'm not really sure why you would want this)
You could do something like this:
interface IMath
{
string DoMath();
}
abstract class MathBase : IMath
{
protected double Total { get; set; }
public abstract string DoMath();
}
class Add : MathBase
{
public override string DoMath()
{
this.Total = 2;
return "2";
}
}

Adding a setter to a virtual property in C#

I have a situation like this:
public abstract class BaseClass
{
public abstract string MyProp { get; }
}
Now, for some of the derived classes, the properties value is a synthesized values, so there is no setter:
public class Derived1 : BaseClass
{
public override string MyProp { get { return "no backing store"; } }
}
This works fine. However, some of the derived class required a more traditional backing store. But, no matter how I write it, as on automatic property, or with an explicit backing store, I get an error:
public class Derived2 : BaseClass
{
public override string MyProp { get; private set;}
}
public class Derived3 : BaseClass
{
private string myProp;
public override string MyProp
{
get { return myProp;}
private set { myProp = value;}
}
}
Derived2.MyProp.set': cannot override because 'BaseClass.MyProp' does not have an overridable set accessor
How do I get this to work??
The best thing you can do is implement the property as virtual instead of abstract. Make the get and set blocks for each throw NotSupportedException in the base class and override the behaviour accordingly in derived classes:
public virtual string MyProp {
get {
throw new NotSupportedException();
}
set {
throw new NotSupportedException();
}
}
Basically, you cannot. By adding a setter you are changing the definition of the property, so it does not really "override" the base property. It's the same as if you tried to override a method and add another parameter to it - they would be treated as different methods (overloaded). Since properties cannot be overloaded this won't work.
You'll just have to add another method to set the value (perhaps with protected accessibility).
Bradley's suggestion is good, but one thing I've done in cases where only the Setter should be virtual is to do something this this:
public class Root
{
private string _MyProp;
public string MyProp
{
get { return _MyProp;}
set { _MyProp = SetMyProp(value); }
}
protected virtual string SetMyProp(string suggestedValue)
{
return suggestedValue;
}
}
public class Child
: Root
{
protected override string SetMyProp(string suggestedValue)
{
string oReturn = base.SetMyProp(suggestedValue);
// Do some sort of cleanup here?
return oReturn;
}
}
It requires a little extra work up front, but it seems to maintain a higher degree of encapsulation (e.g. you can prevent subclasses from overriding the Getter behavior, and your subclass doesn't have to be aware of the underlying member behind the property).
I would suggest avoiding virtual or abstract properties. Instead, use a non-virtual property which chains to protected virtual or abstract get/set methods. Doing that will allow derived classes to override the methods and also shadow the property with one that has different access modifiers. Since the base property itself will be non-virtual, there will never be any need to override it, so the naming conflict with the new version won't matter.

c# property override Set method

I have a class like the below, I want to override the set value of "School,Country..etc.." property when some one sets a value , i don't want to change the student class but i need to do it in the base class and use it as a generic method
public class Student : BaseClass
{
public String School { get; set; }
public String Country{ get; set; }
}
ie:
When some one sets
Student.School="Harvard",
I need to store it as
Student.School="Harvard my custom value";
Note:
Basically calling OnPropertyChanged in base class rather than the main class.
If you want to do it with aspects, then try Postsharp
Basically you cannot override a non-virtual property. You can hide it by other property with the same name in the derived class, but this won't give you the desired effect if some other code accesses your object by the reference to the base class.
public class Student : BaseClass
{
private string _school
public string School
{
get { return _school; }
set
{
if(value == "Harvard")
value = "Harvard custom";
_school = value;
}
}
public String Country{ get; set; }
}
is that what you mean?
If the School property is in the BaseClass then you can either use the new keyword, or if you control the BaseClass, then you can add the virtual keyword to the School property there, and override it in the Student class.
This is just not doable by solely modifying BaseClass. Think about it this way: If it were possible to "annotate" automatic properties that easily, then we wouldn't need all those <rant>useless tons of</rant> manual property implementations for data model classes that implement INotifyPropertyChanged (same for DependencyProperties).
You need to provide hooks in your subclasses that your base class can use. Implementing PropertyChanged, which you already mentioned, is one possible solution, another one would be a simple method call:
public class Student : BaseClass
{
private string _school;
public String School
{
get { return _school; }
set {
_school = value;
DoMoreChanges(ref _school); // DoMoreChanges is defined in BaseClass
}
}
public String Country{ get; set; }
}
If you have lots of subclasses that need this, you can either use Visual Studio Code Snippets to create the code or T4 templates.
Since your base class does not have those properties you will not be able to modify them from within the base class using standard OOD patterns or principles.
Now if you move the properties to your base class either as normal properties or virtual properties you can modify what you do in the set block of the properties to do extra work.
However if you cannot move these to the base class, and you cannot modify the Student class, as you seem to imply in you question, then you could encapsulate the student class within a new class like StudentProxy or something and then have it expose similar properties that will then call into the real student class how you want.
For example:
public class StudentProxy
{
private Student _student;
public StudentProxy(Student student)
{
this._student = student;
}
public String School
{
get { return _student.School; }
set
{
_student.School = value + " my custom value";
}
}
public String Country
{
get { return _student.Country; }
set
{
_student.Country = value + " my custom value";
}
}
}

c# hide from dervied classes some properties of base class

I want to know if its possible to hide a base class property from a derived class:
Example:
class BaseDocument
{
public string DocPath{get; set;}
public string DocContent{get; set;}
}
class DerviedDocument: BaseDocument
{
//this class should not get the DocContent property
public Test()
{
DerivedDocument d = new DerivedDocument();
d.//intellisense should only show me DocPath
//I do not want this class to see the DocContent property
}
}
I cannot make the DocContent property private, because I want to instantiate the BaseDocument class elsewhere and use the property there. That will kill the idea of a property anyway.
One way to fix this would be to use a interface, say IDoc, which exposes DocPath property and make both the BaseDocument and DerivedDocument implement the interface. This will break their parent-child relationship though.
I can play with the new and override keywords, but that's not the right way either because the child still 'sees' the property
I tried using the 'sealed' keyword on the DocContent, but that does not seem to solve the problem either.
I understand that it 'breaks' inheritance, but I guess this scenario should be coming up frequently where a child needs to get everything else from the parent but one or two properties.
How can such scenarios be handled gracefully?
I'm not sure inheritance would be the way to go here. Yes, you can hack around it by using the EditorBrowsableAttribute but I think the design should be rethought. One possible approach:
public interface IDoc
{
DocPath{get;set;}
}
class BaseDocument : IDoc
{
public DocPath{get; set;}
public DocContent{get; set;}
}
class DerviedDocument
{
public DerivedDocument(IDoc doc)
{
this.Doc = doc;
}
public IDoc Doc{get;set;}
public Test()
{
DerivedDocument d = new DerivedDocument(new BaseDocument());
d.//here you will only see d.IDoc which only exposes DocPath
}
}
Basically, use composition instead of inheritance, and program to an interface, not to an implementation.
You can do it easily if you don't mind having BaseDocument and DerivedDocument in different assemblies/projects.
Make DocContent internal. It'll be visible to everything in the same project as BaseDocument, but it won't be visible to DerivedDocument since that's in a different project. Of course, you'll need to make BaseDocument public (right now you have it as the default, internal).
In first project:
public class BaseDocument
{
public string DocPath {get; set;}
internal string DocContent {get; set;}
}
In second project that references first:
class DerivedDocument : FirstProject.BaseDocument
{
public Test()
{
DerivedDocument d = new DerivedDocument();
d. //intellisense shows DocPath, but not DocContent
}
}
This solution has the advantage of not being a kludge. You can still use BaseDocument's DocContent property within BaseDocument's project. If you need to use DocContent in another project (separate from the project DerivedDocument is in), you can use the InternalsVisibleTo attribute to make DocContent visible to that assembly. (That, however, is in my opinion a kludge, albeit a very handy one in some scenarios.)
It sounds like you want to intentionally violate the Liskov Substitution Principle. Why bother with subclassing at all if it's not going to have the conventional inheritance semantics? Just make a separate class.
interface IBaseDocument
{
string DocPath { get ; set ; }
string DocContent { get ; set ; }
}
class BaseDocument : IBaseDocument
{
public string DocPath { get ; set ; } // implement normally
private string MyDocContent ; // use this in BaseDocument
string IBaseDocument.DocContent // implement explicitly
{
get { return MyDocContent ; }
set { MyDocContent = value ; }
}
}
class DerviedDocument : BaseDocument
{
public void Test ()
{
// error: The name 'DocContent' does not exist in the current context
Console.WriteLine (DocContent) ;
}
}
A late reaction, but there are several ways to do this.
Most beautiful: Place your Base class in a separate assembly and mark the property DocContent as internal instead of public:
class BaseDocument
{
public string DocPath{get; set;}
internal string DocContent{get; set;} //won't be visible outside the assembly
}
Or use attributes to hide the property from the source editor:
class BaseDocument
{
public string DocPath{get; set;}
public string DocContent{get; set;}
}
class DerviedDocument: BaseDocument
{
//this class should not get the DocContent property
[Browsable(false), EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public new string DocContent{ get; set; }
public Test()
{
DerivedDocument d = new DerivedDocument();
d.//intellisense will only show me DocPath
//I do not want this class to see the DocContent property
}
}
I don't believe there is a good (or any) way to do this. You may have to break the hierarchy, or you could remove the DocContent property from BaseDocument, then derive two sepearate classes from BaseDocument, one which is your current DerivedDocument, and another which has the DocContent property.
Just do this.
class BaseDocument
{
public DocPath{get; set;}
public virtual DocContent{get; set;}
}
class DerviedDocument: BaseDocument
{
public override DocContent
{
get { return null; }
set { }
}
}
Or
public override DocContent
{
get { throw new NotImplementedException("Do not use this property!"); }
set { throw new NotImplementedException("Do not use this property!"); }
}

Field belongs to a class, but how to use polymorphism

I have a method in a base class
class Base
{
private static string Colour = "blue";
string DoStuff() { return ColourProp; }
protected virtual string ColourProp { get{ return Base.Colour; } }
}
that is called on an instance of this subclass
class Sub
{
private static string Colour = "orange";
protected override string ColourProp { get{ return Sub.Colour; } }
}
At the moment I'm using virtual properties, is this the only way? (considering that fields cannot be virtual)...
Yes, you do need to use either a virtual property or a virtual method to accomplish this. The CLR will dynamically dispatch all calls to ColourProp correctly based on the type of the object (i.e. polymorphism).
This looks totally fine. Don't worry about virtual properties. This provides not only an encapsulation of your data against other objects but also against subclasses.

Categories

Resources