0
votes
I came across a lot of code in our company codebase with the following structure



   class Base
    {
     public Base (var a, var b)
     {
      base_a = a;
      base_b = b;
     }

     var base_a;
     var base_b;
    }

    class Derived:Base
    {
     publc Derived (var a,b,c,d): base (a,d)
     {
       der_c = c;
       der_d = d;  
     }
     var der_c;
     var der_d;
     var der_e;
    }


    class  Ref
    {
     Base _ref;
     public Ref( var a,b,c,d)
     {
      _ref = new Derived (a,b,c,d)
     }

     public void method( )
     {
       _ref.der_e = 444; // won't compile
     }
    }

What is the correct way to initialize der_e ? What is the advantages of having a reference of base class and using an object derived class for _ref ? Just the fact that using a base class reference can hold multiple derived class objects ? If that's the case, should all the member variables of derived class be initialized during construction itself (like this: _ref = new Derived (a,b,c,d) ). What if I want to initialize _ref.der_e later in a method ? I know I can do this (var cast_ref = _ref as Derived; cast_ref.der_e = 444) but this look doesn't seem to the best practice. What is the idea of having such a structure and what is the correct of initializing a member of a derived class object after it has been constructed ?

2
The code you've given won't compile at all - you can't use var for parameters or fields (unless you've actually got a class called var). Please give a realistic example - ideally shorter, following .NET naming conventions, and better formatted. - Jon Skeet

2 Answers

0
votes

Those are too many questions in a single post.

What is the correct way to initialize der_e ?

For initializing der_e you will have to have Reference of Derived class as it knows about the der_e property and not Base class.

What is the advantages of having a reference of base class and using an object derived class for _ref ?

Yes that's called Polymorphism which is the essence of Object Oriented Programming. It allows us to hold various concrete implementations without knowing about the actual implementation.

If that's the case, should all the member variables of derived class be initialized during construction itself (like this: _ref = new Derived (a,b,c,d) )

There is no such rule. It depends on your scenario. If the values are not meant to be changed after the creation of the object and the values are known before hand during construction of the object then they should be initialized during construction.

Again if there are various scenarios like sometimes values are known and sometimes not then there can be Overloaded Constructors, which take different arguments.

What if I want to initialize _ref.der_e later in a method ?

That is perfectly fine, it depends on what you are trying to achieve. The question is not a concrete one but an abstract one in which it is difficult to comment on what you are trying to achieve.

I know I can do this (var cast_ref = _ref as Derived; cast_ref.der_e = 444) but this look doesn't seem to the best practice.

I am sharing some Java code which is similar to C# as I am from Java background

//This class knows about Base and nothing about the Derived class
class UserOfBase{

   Base ref; 

   //Constructor of UserOfBase gets passed an instance of Base
   public UserOfBase(Base bInstance){
      this.ref = bInstance;
   }

   //Now this class should not cast it into Derived class as that would not be a polymorphic behavior. In that case you have got your design wrong.

   public void someMethod(){
        Derived derivedRef = (Derived)ref; //This should not happen here
   }

}

I am sharing some references which would help you with this, as I think the answer can be very long to explain.

0
votes

You can create a constructor in your derived class and map the objects or create an extension method like this:

  public static class Extensions 
  {            
        public static void FillPropertiesFromBaseClass<T1, T2>(this T2 drivedClass, T1 baseClass) where T2 : T1
        {
            //Get the list of properties available in base class
            System.Reflection.PropertyInfo[] properties = typeof(T1).GetProperties();

            properties.ToList().ForEach(property =>
            {
                //Check whether that property is present in derived class
                System.Reflection.PropertyInfo isPresent = drivedClass.GetType().GetProperty(property.Name);
                if (isPresent != null && property.CanWrite)
                {
                    //If present get the value and map it
                    object value = baseClass.GetType().GetProperty(property.Name).GetValue(baseClass, null);
                    drivedClass.GetType().GetProperty(property.Name).SetValue(drivedClass, value, null);
                }
            });
        }
  }

for example when you have to class like this:

public class Fruit {
    public float Sugar { get; set; }
    public int Size { get; set; }
}
public class Apple : Fruit {
    public int NumberOfWorms { get; set; }
}

you can initialize derived class by this code:

//constructor 
public Apple(Fruit fruit)
{            
   this.FillPropertiesFromBaseClass(fruit);
}