Not sure when to use 'base' in C #

I'm trying to teach myself OOP in C #, but I have a question about when to use it base. I understand the general principles, but I'm not sure what is best in the example below. This simple test includes:

  • An interfacewith two propertiesstring
  • A class abstractthat implements this interface and adds a couple more propertiesstring
  • Two classes implementing an abstract class. One uses base, and the other does not, but both of them produce the same output when executing the program.

My question is: in this example, is one implementation more desirable than another ? I'm not sure if there are any significant differences between TranslationStyleAand TranslationStyleB, or if it's just personal preference?

Thanks so much 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();
        }
    }
}
+3
source share
5 answers

The first thing you need to understand is what happens when you have an automatic property:

public virtual string English { get; set; }

Behind the scenes, the compiler creates a private field and gets / sets this private field when accessing the property. It is equivalent to this

private string _english;
public virtual string English { get { return _english; } set { _english = value; } }

except that you do not know the name of the private field, and therefore you cannot access it.

, TranslationStyleA , .

    // 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; }
    }

TranslationStyleB ( ). , English , , :

    private string english;
    public override string English
    {
        get { return english; }
        set { english = value; }
    }

, , , , . , , , .

, . , , .

    // 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(); }
    }

, - . , :

public String Foo;
public String Foo { get; set; } // <-- why bother with all this extra { get; set; } stuff?

, . ,

public String Foo;

public String Foo { get; set; }

, . ,

public String Foo { get; set; }

to

private string _foo;
public String Foo { get { return _foo; } set { _foo = value.Trim(); } }

( ).

(Translation) English, :

private string _english;
public String English { get { return _english; } set { _english = value.ToUpper(); } }

!

, , , , , .

+4

, .

Translation , B , , . A , , .

, , . :

public class TranslationStyleC : Translation {
    public TranslationStyleC(string e, string f) : base(e, f) {
    }
}
+3

- , , - .

abstract Translation, , .

, base; , , . base ; virtual ( ). , base, .

+2

, A , , B . , base, " , /, ".

+1

, .

, TranslationStyleA , , . , .

The second implementation is common when you really want to redefine the setting and gain access to the elements of the base class, for example, if the setting of the element of the base class is a catalyst for starting another operation, then the redefined member at the output will be a suitable place for this.

+1
source

All Articles