C # type inference: fails if it shouldn't?

Pay attention to the following code. The line of insult was commented.

interface I<R> { } class C : I<int> { } class Program { private static void function<T, R>(T t) where T : class, I<R> { } static void Main(string[] args) { // function(new C()); // wont compile function<C, int>(new C()); } } 

I believe that type inference should determine the type, because the argument T provides the first type, and I<R> second type.

Is there a way to redesign the function so that callers do not have to specify types?

+4
source share
5 answers
 class D : I<int>, I<string> { } // function<D, int>(new D()); function<D, string>(new D()); //is R int or string? function(new D()); 
+4
source

Not if you want to keep all restrictions. However, this should be equally good if you have no particular reason to prohibit value types:

 private static void function<R>(I<R> t) 
+8
source

There are various ways to add additional rules for input input - bits of logic that a person can apply, but the compiler (obeying the language specification) does not.

Before you suggest updating the language to make type inference more flexible, I highly recommend that you familiarize yourself with the existing specification. If you can understand that it's easy enough that you still think it's worth it to be even more complicated, send the feature request to Connect - but personally, I think it's pretty complicated. I would say that this is much better than in C # 2.0.

To put forward the opposite opinion, however, several languages ​​(especially functional ones) have more powerful type inference mechanisms. There are always pros and cons here - I believe that one of the advantages of the current output system in C # is that it always makes progress or stops, for example - Eric Lippert Blog contains additional information about this and a number of other output problems.

+5
source

No, C # does not support this conclusion.

Use the interface directly and find the type with type get ..

 private static void function<R>(I<R> t) { Type typeofT = typeof(T); } 

can't do better.

If you need to call another generic method using T, you can build a generic call through reflection using typeofT Type.

+1
source

C # does not support this type of output. Consider this case, which adds some ambiguity to the problem.

 class Other : I<int>, I<Student>{ ... } void Example(){ function(new D()); } 

In this case, there is an ambiguity that I have to choose.

If you look forward to C # 4.0, the problem will only increase with the new dispersion features that they add.

+1
source

All Articles