为什么不这样code编译VS2010与.NET 4.0?code、NET

2023-09-03 16:01:15 作者:安如少年初如夢

不知何故以下code在VS2010没有编译,但编译在VS2012没有变化。在VS2010的问题行

  names.Select(foo.GetName)
 

  

错误CS1928:'字符串[]'不包含对选择和定义的最佳扩展方法重载'System.Linq.Enumerable.Select<TSource,TResult>(System.Collections.Generic.IEnumerable<TSource>, System.Func&LT; TSource,TResult&GT;)有一些无效的参数

 使用系统;
使用System.Linq的;

命名空间ConsoleApplication1
{
    类节目
    {
        静态无效的主要()
        {
            无功富=新的Foo();
            VAR名称=新的[] {你好};
            Console.WriteLine(的string.join(,,names.Select(foo.GetName)));
        }
    }

    公共类Foo
    {
    }

    静态类扩展
    {
        公共静态字符串的GetName(这个富富,字符串名称)
        {
            返回名称;
        }
    }
}
 

解决方案

更新答案

我已经检查了code段 names.Select(foo.GetName)编译在VS 2012,并没有就VS2010。

我DONOT知道原因(准确的说在C#5.0和.NET 4.5或新的API中的新功能),使得有可能。

但随之而来的错误

 的方法的类型参数'System.Linq.Enumerable.Select<TSource,TResult>(System.Collections.Generic.IEnumerable<TSource>, System.Func&所述; TSource,TResult&GT)'不能从使用的推断。请尝试显式指定类型参数。
 
ubuntu下的vscode

看起来 Enumerable.Select 是不是能够推断出参数和返回 foo.GetName 的类型。

指定类型,code编译。

以下是3种选择

1。铸造 Func键&LT;字符串,字符串&GT;

 的string.join(,names.Select&LT;字符串,字符串&GT;(foo.GetName).ToArray())
 

2。指定在类型,泛型参数选择条款

 的string.join(,names.Select((Func键&LT;字符串,字符串&GT;)foo.GetName).ToArray())
 

3。在匿名委托显式调用功能。

  Console.WriteLine(的string.join(,names.Select(名称=&GT; foo.GetName(名称))))
 

但作为乔恩斯基特指出在评论上面会创建一个新的方法添加另一个函数调用。

原来的答案

  

为什么code没有在VS2010编译.NET 4.0?

您没有传递参数的名称。你传入的方法名,在 Func键&LT; T1,T2&GT;

下面将被编译

  Console.WriteLine(的string.join(,names.Select(名称=&GT; foo.GetName(名称))))
 

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;
        }
    }
}

解决方案

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))))

 
精彩推荐
图片推荐