0

Is there an equivalent in c# for the following code in Java

List<? extends Number> list;
list = new ArrayList<Float>();
list = new ArrayList<Integer>();
list.add(Float.valueOf("4.0")); // doesn't compile and it is fine
Number e = list.get(0); // workds

I was reading about covariant types in c#

List<SomeClass> list2 = new List<SomeClass>();
IEnumerable<Object> list3 = list2; // works

From whatever I understand all the interfaces/classes in Java are supporting covariance by default. Depending on the type parameter used in the declaration, features (method that take the parameterized types as input) that don't follow covariance are not supported. Meaning, List<? extends Number> can take a reference of List<Integer> or a List<Double>, but it would no longer support methods like add().

Now, on the other side in C#, looks like I need to find an interface that supports Covariance and then use it. So, whenever I want to write some generic class, I have to write a separate interface that supports all covariant operations for all derived classes and make sure my class implements that interface? Is this correct or am I missing something.

Thanks

Gopal
  • 1,292
  • 3
  • 19
  • 41
  • 1
    You are correct, and I think that this is due to the way generics are implemented in .Net vs Java. If I understand it correctly, there are no generics in JVM bytecode, while in .Net they are baked into CIL. Compiler implementations of each is based on these facts, so Java compiler performs *type erasure* only for code paths used in the program, while C# compiler has to ensure integrity of all the use cases. Some info from a real expert here: http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens. Besides, there's nothing like base Number in C#. – galenus Oct 19 '13 at 11:43

1 Answers1

1

Your question,
Is there an equivalent in c# for the following code in Java

    List<? extends Number> list;
    list = new ArrayList<Float>();
    list = new ArrayList<Integer>();
    list.add(Float.valueOf("4.0")); // doesn't compile and it is fine
    Number e = list.get(0); // workds

No, directly there is no equivalent as there is no base or super class or interface for 'Number' but there is an Equivalent(sort of for '?' operator), the where keyword.

You can get more information about it on msdn page about it.

You can do this inline for a variable in class simply as:

public class ArrayList<T> where T: someBaseClass
{
   List<T> list = new List<DerivedTypeOfSomeBaseClass>();
}

or inside a function

public T getArrayList<T>(ArrayList<T> arr) where T: someBaseClass
List<T> list = new List<DerivedTypeOfSomeBaseClass>()

Your question

Now, on the other side in C#, looks like I need to find an interface that supports Covariance and then use it. So, whenever I want to write some generic class, I have to write a separate interface that supports all covariant operations for all derived classes and make sure my class implements that interface? Is this correct or am I missing something

General concept of Covariance and contravariance states that, covariance is the ability to use a more derived type than that specified by the generic parameter, whereas contravariance is the ability to use a less derived type.
For a detailed description about Covariance and Contravariance you can read MSDN link.
So, you are right if you want to do the thing through Generic way you have to have a common base interface that supports all covariant operations.

In your specific case for numbers all the Byte, Double, Float, Integer, Long, Short in C# implements IComparable, IFormattable, IConvertible, IComparable, IEquatable interfaces, so for your first question,

 public class Program<K> where K : IComparable, IFormattable, IConvertible, IComparable<K>, IEquatable<K>
{
  static void Main()
  {  
        Program<int> pro = new Program<int>();
        Program<Byte> bpro = new Program<Byte>();
        Program<Double> dpro = new Program<Double>();
        Program<Int64> fpro = new Program<Int64>();
        Program<long> lpro = new Program<long>();
        Program<short> spro = new Program<short>();
   }
Deepak Bhatia
  • 6,230
  • 2
  • 24
  • 58