Different return type from a method of a derived class

In .NET Framework 4, C# supports covariance and contravariance in generic interfaces and delegates. However, if you try to implement either in a class, you will receive an exception. Trying to implement covariance in a return type or overriding a method and attempting to return a different type will not work. Let’s discuss below.

public class Class1
{
     public virtual List<string> MethodToReturnSomething()
     {
         List<string> list = new List<string>();
         list.Add("Class1 String");
         return list;
     }
}
 
public class Class2 : Class1
{
     public override List<int> MethodToReturnSomething()
     {
         List<string> list = new List<string>();
         list.Add("Class2 String");
 
         List<int> intList = new List<int>();
         intList.Add(100);
         
         return intList;
     }
}

The above will result in a exception because the MethodToReturnSomething() in the base class returns a List of string and in the derived class I try to return a List of integers.

Something I found while trying to implement my solution was generics. I created another class which would accept any type and then simply returned that value. Of course you would put more code to meet your requirements.

public class Class3<T>
{
     public virtual T MethodToReturnSomethingGeneric(T item)
     {
         return item;
     }
}
 
Class3<int> cl4 = new Class3<int>();
Console.WriteLine("Class3 int: " +
   cl4.MethodToReturnSomethingGeneric(100).ToString());
Console.WriteLine();
 
Class3<string> cl5 = new Class3<string>();
Console.WriteLine("Class3 string: " +
   cl5.MethodToReturnSomethingGeneric("C# Rocks!").ToString());
Console.WriteLine();

Therefore, when I pass the MethodToReturnSomethingGeneric() method any type, it would return that type back. In the first method I sent an Integer and the second a string.

And to prove it was inheritable, I created this class and overrode the method.

public class Class4<T> : Class3<T>
{
     public override T MethodToReturnSomethingGeneric(T item)
     {
         return item;
     }
}

I can’t say that I recommend this approach, I ended up using the new keyword for the method I needed to return a different type in my derived class. Simply because the above would have resulted in too much rewrite.

It was a very interesting exercise to work through these generics and am beginning to enjoy implementing then in my code.

Download the source