Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this code compile in VS2010 with .NET 4.0?

Somehow following code doesn't compile in VS2010 but compiles in VS2012 without changes. The problematic line in VS2010 is

names.Select(foo.GetName)

error CS1928: 'string[]' does not contain a definition for 'Select' and the best extension method overload 'System.Linq.Enumerable.Select<TSource,TResult>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,TResult>)' has some invalid arguments.

using System;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            var foo = new Foo();
            var names = new[] {"Hello"};
            Console.WriteLine(string.Join(", ", names.Select(foo.GetName)));
        }
    }

    public class Foo
    {
    }

    static class Extensions
    {
        public static string GetName(this Foo foo, string name)
        {
            return name;
        }
    }
}
like image 818
wangzq Avatar asked Jan 14 '13 14:01

wangzq


People also ask

What is the .NET framework for Visual Studio 2010?

The functionality of Visual Studio 2010, . NET Framework 4 and Silverlight 4 creates a powerful and unique combination, opening up new opportunities for developers to build applications that take advantage of new and existing devices, as well as emerging platforms like cloud services.”

Does Visual Studio support Visual Basic?

Visual Studio supports 36 different programming languages and allows the code editor and debugger to support (to varying degrees) nearly any programming language, provided a language-specific service exists. Built-in languages include C, C++, C++/CLI, Visual Basic .


2 Answers

Updated Answer

I have checked that the code snippet names.Select(foo.GetName) compiles in VS 2012, and does not compile on VS2010.

I donot know the reason (To be exact the new feature in C# 5.0 or .NET 4.5 or new API) that made it possible.

But following the error

The type arguments for method 'System.Linq.Enumerable.Select<TSource,TResult>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,TResult>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

It Seems like Enumerable.Select is not able to infer the parameter and return type of foo.GetName.

Specifying the type, code will compile.

Following are the 3 options

1 . Casting to Func<string,string>

string.Join(", ", names.Select<string,string>(foo.GetName).ToArray())

2 . Specifying types as generic parameters in Select clause

string.Join(", ", names.Select((Func<string,string>)foo.GetName).ToArray())

3 . Call Function explicitly in anonymous delegate.

 Console.WriteLine(string.Join(", ", names.Select( name => foo.GetName(name))))

But as Jon Skeet pointed in comments the above will add another function call by creating a new method.

ORIGINAL Answer

why this code doesn't compile in VS2010 with .NET 4.0?

You are not passing Parameter to the name. You are passing method name, in place of Func<T1,T2>.


Following will be compiled

Console.WriteLine(string.Join(", ", names.Select( name => foo.GetName(name))))
like image 55
Tilak Avatar answered Oct 05 '22 02:10

Tilak


I had this same problem in VSS 2010. I got it fixed by changing the target framework to 3.5. then trying to build. As expected, your build will fail BUT this kick starts or resets some internal flag in VSS 2010. Now, switch back to .NET 4.0 and VSS will start building properly.

like image 31
Juls Avatar answered Oct 05 '22 03:10

Juls