Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# Why can't open generic types be passed as parameters?

Tags:

c#

generics

Why can't open generic types be passed as parameters. I frequently have classes like:

public class Example<T> where T: BaseClass
{
   public int a {get; set;}
   public List<T> mylist {get; set;}
}

Lets say BaseClass is as follows;

public BaseClass
{
    public int num;
}

I then want a method of say:

public int MyArbitarySumMethod(Example example)//This won't compile Example not closed
{
   int sum = 0;
   foreach(BaseClass i in example.myList)//myList being infered as an IEnumerable
       sum += i.num;
   sum = sum * example.a;
   return sum;
}

I then have to write an interface just to pass this one class as a parameter as follows:

public interface IExample
{
public int a {get; set;}
public IEnumerable<BaseClass> myIEnum {get;}
}

The generic class then has to be modified to:

public class Example<T>: IExample where T: BaseClass
{
   public int a {get; set;}
   public List<T> mylist {get; set;}
   public IEnumerable<BaseClass> myIEnum {get {return myList;} }
}

That's a lot of ceremony for what I would have thought the compiler could infer. Even if something can't be changed I find it psychologically very helpful if I know the reasons / justifications for the absence of Syntax short cuts.

like image 465
Rich Oliver Avatar asked Mar 20 '12 22:03

Rich Oliver


1 Answers

I have been in similar situation, but I never had this (very good!) question. Now that I am forced to think about it, here is my answer:

You expect the following to work:

void F(Example<> e) {
   Console.WriteLine(e.a); //could work
}

Yeah, this could theoretically work, but this won't:

void F(Example<> e) {
   Console.WriteLine(e.mylist); //?? type unknown
}

You expect the compiler and CLR to be able to analyze method bodies and proove that really no unsafe access is possible in the first case. That could be made to work. Why wasn't it? Probably, the design is not really sound and confusing. Also, "all features are unimplemented by default. Somebody must implement, test and document them."

Edit: I want to point out that this feature cannot be implemented without cooperation from the CLR. The C# compiler must emit the exact method to be called which is not possible on an open generic type. The type system does not even allow such a variable right now.

like image 119
usr Avatar answered Oct 04 '22 19:10

usr