Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't the C# compiler automatically infer the types in this code?

Why does the C# compiler not infer the fact that FooExt.Multiply() satisfies the signature of Functions.Apply()? I have to specify a separate delegate variable of type Func<Foo,int,int> for the code to work ... but it seems like type inference should handle this. Am I wrong? And, if so, why?

EDIT: The compilation error received is:

The type arguments for method FirstClassFunctions.Functions.Apply<T1,T2,TR>(T1, System.Func<T1,T2,TR>, T2)' cannot be inferred from the usage. Try specifying the type arguments explicitly

namespace FirstClassFunctions  {
    public class Foo  {
        public int Value { get; set; }

        public int Multiply(int j) {
            return Value*j;
        }
    }

    public static class FooExt  {
        public static int Multiply(Foo foo, int j) {
            return foo.Multiply(j);
        }
    }

    public static class Functions  {
        public static Func<TR> Apply<T1,T2,TR>( this T1 obj, 
                                                Func<T1,T2,TR> f, T2 val ) {
            return () => f(obj, val);
        }
    }


    public class Main  {
        public static void Run()  {
            var x = new Foo {Value = 10};
            // the line below won't compile ...
            var result = x.Apply(FooExt.Multiply, 5);
            // but this will:
            Func<Foo, int, int> f = FooExt.Multiply;
            var result = x.Apply(f, 5);
        }
    }
like image 371
CluelessCoder Avatar asked Nov 15 '10 21:11

CluelessCoder


People also ask

Why is there no string in C?

There is no string type in C . You have to use char arrays. By the way your code will not work ,because the size of the array should allow for the whole array to fit in plus one additional zero terminating character.

Why C has no exception handling?

As such, C programming does not provide direct support for error handling but being a system programming language, it provides you access at lower level in the form of return values. Most of the C or even Unix function calls return -1 or NULL in case of any error and set an error code errno.

Why is C not outdated?

The C programming language doesn't seem to have an expiration date. It's closeness to the hardware, great portability and deterministic usage of resources makes it ideal for low level development for such things as operating system kernels and embedded software.

Why array bounds checking is not available in C?

This is due to the fact that C++ does not do bounds checking. Languages like Java and python have bounds checking so if you try to access an out of bounds element, they throw an error. C++ design principle was that it shouldn't be slower than the equivalent C code, and C doesn't do array bounds checking.


1 Answers

I believe this is the result of the VS2008 C# compiler's inability to correctly infer the types involved when converting a method group to a delegate. @Eric Lippert discusses this behavior in his post C# 3.0 Return Type Inference Does Not Work On Method Groups.

If I recall correctly, some improvements were made in the new C# compiler that's part of VS2010 which expands the cases where method group inference is possible.

Now, the rules for type inference are quite complicated, and I'm far from an expert in this subject. Hopefully someone with some real knowledge can address this question if I am mistaken.

like image 52
LBushkin Avatar answered Sep 25 '22 14:09

LBushkin