Home > Back-end >  Given a base and extended class, is casting always needed for base class methods that return objects
Given a base and extended class, is casting always needed for base class methods that return objects

Time:04-30

Assume this base class:

public class BaseClass {
    public BaseClass Clone() { 
        /* Returns a full copy of the object. */ 
   }

    /* Constructors here */
}

And this derived class:

public class ExtendedBaseClass : BaseClass {
    /* ... */

   /* Constructors here */
}

If I understand correctly, if an instance of ExtendBaseClass, calls Clone, an object of type BaseClass will be returned. So, this will fail because an explicit cast is missing:

BaseClass bc = new();
ExtendedBaseClass ebc = bc.Clone();

I have two questions:

  1. Is my understanding correct?
  2. Is there a way to prevent an explicit cast from being needed when Clone() is called?

CodePudding user response:

It depends on how the copy is done - an ExtendedClass is a BaseClass, so if Clone looks at the runtime type and creates a new instance of that same type, then the object returned from Clone will be an ExtendedClass. But, you will need a cast to tell the compiler that the object is an ExtendedClass, otherwise the compiler will treat it as a BaseClass for method binding and other operations.

Or, make BaseClass and Clone generic:

public class BaseClass<T> where T:BaseClass<T> {
    public T Clone() { 
        /* Returns a full copy of the object. */ 
   }

    /* Constructors here */
}

public class ExtendedBaseClass : BaseClass<ExtendedBaseClass> {
    /* ... */

   /* Constructors here */
}

ExtendedBaseClass original;
ExtendedBaseClass copy = original.Clone();

Then the compiler will know that Clone returns an ExtendedBaseClass and you won't need a cast.

Note that this is still not fool-proof, since technically you can define

public class ExtendedBaseClass2 : BaseClass<ExtendedBaseClass> {
    /* ... */

   /* Constructors here */
}

and Clone will return an ExtendedBaseClass.

CodePudding user response:

This is one way, if you are using C# 9.

Covariant return types c# 9

Support covariant return types. Specifically, permit the override of a method to declare a more derived return type than the method it overrides,

Try in net fiddle


using System;
                   
public class Program
{
   public static void Main()
   {
       var a = new Derived("XYZ");
       var b = a.Clone();
       Console.WriteLine(b.Name);
       
   }
   
  public abstract class BaseClass
  {
      public abstract BaseClass Clone();
  }
  public class Derived : BaseClass
  {
      public Derived(string name)
      {
          Name = name;
      }
      public string Name {get;}
       public override Derived Clone()
       {
         return new Derived(this.Name);
       }
  }
}
  •  Tags:  
  • c#
  • Related