为什么我不能在VB中投影ToString()?

R. *_*des 18 linq vb.net

如果您尝试在Visual Basic .NET中编译下面的查询,它将失败.

From x In {1, 2} Select x.ToString()
Run Code Online (Sandbox Code Playgroud)

编译器给出的错误是:

范围变量名称不能与"对象"类的成员名称匹配.

但是,等效的C#查询没有任何问题:

from x in new[]{1, 2} select x.ToString()
Run Code Online (Sandbox Code Playgroud)

ToString采用格式的重载(它是Int32的成员,而不是Object)不会发生这种情况.它使用对象的其他成员发生,只要他们不带任何参数:使用的GetType和GetHashCode失败; 使用Equals(对象)进行编译.

为什么会出现这种限制,我可以使用哪些替代方案?

tny*_*fst 36

我无法告诉你为什么 VB有这种荒谬,但简单的解决方法是将方法调用放在parens中.

Dim q = From x In {1, 2} Select (x.ToString())
Run Code Online (Sandbox Code Playgroud)

  • 我的脑袋爆炸了. (6认同)

Dan*_*Tao 11

这是我理解它的方式.请考虑以下代码:

Dim q = From x In {"Bob", "Larry"}
        Select x.Length
        Select Length * 2
Run Code Online (Sandbox Code Playgroud)

在上面的查询中,VB编译器根据表达式自动 "猜测" Length变量的名称.现在,你没有要求这个; 它只是一个功能,无论你喜欢与否.但现在考虑一下:x.Length

Dim q = From x In {"Bob", "Larry"}
        Select (x.Length)
        Select Length * 2
Run Code Online (Sandbox Code Playgroud)

上面的代码没有编译,因为第一Select个子句中的表达式并不像第一种情况那样简单(信不信由你); 括号使事情变得复杂,以至于编译器不会选择名称Length; 相反,它生成一个不能从代码中使用的名称.

所以基本上与发生的事情ToString()是,这个表达式是很简单的编译器使用,以产生一个变量名,它可能如果查询扩大到使用这个变量,例如可以使用:

Dim q = From x In { 1, 2 }
        Select x.ToString()
        Select ToString.Length
Run Code Online (Sandbox Code Playgroud)

但是,ToString它不是变量的合法名称,因为它是一个成员System.Object(为什么LINQ查询中的变量会出现这种情况,但对于标准局部变量则不然,我不能说).


Kob*_*obi 5

虽然我无法提供有关错误的详细信息,但有一个简单的解决方法:

From x In {1, 2, 3} Let str = x.ToString() Select str
Run Code Online (Sandbox Code Playgroud)

当你有以下几行时,它的价值是多少:

Dim b = From num In {1, 2, 3} Select num.ToString("d")
Run Code Online (Sandbox Code Playgroud)

它是编译和反编译(使用Reflector,C#):

public class Class1
{
    [CompilerGenerated]
    private static string _Lambda$__1(int num)
    {
        return num.ToString("d");
    }

    public void Test1()
    {
        IEnumerable<string> b = new int[] { 1, 2, 3 }
            .Select<int, string>(new Func<int, string>(Class1._Lambda$__1));
    }
}
Run Code Online (Sandbox Code Playgroud)

沿途似乎没有任何匿名课程.