Why can't I project ToString() in VB?

前端 未结 3 1864
不知归路
不知归路 2020-12-11 00:25

If you try to compile the query below in Visual Basic .NET, it fails.

From x In {1, 2} Select x.ToString()

The error given by the compiler

相关标签:
3条回答
  • 2020-12-11 01:15

    Here's how I understand it. Consider the following code:

    Dim q = From x In {"Bob", "Larry"}
            Select x.Length
            Select Length * 2
    

    In the query above, the name of the Length variable is automatically "guessed" for you by the VB compiler based on the expression x.Length. Now, it's true that you didn't ask for this; it's just a feature that's provided whether you like it or not. But now consider this:

    Dim q = From x In {"Bob", "Larry"}
            Select (x.Length)
            Select Length * 2
    

    The above does not compile because the expression inside the first Select clause is not as simple as in the first case (believe it or not); the parentheses complicate matters just enough for the compiler not to pick the name Length; instead, it generates a name that is not usable from code.

    So basically what's happening with ToString() is that this expression is simple enough for the compiler to use to generate a variable name, which could be used if the query were expanded to make use of this variable, e.g.:

    Dim q = From x In { 1, 2 }
            Select x.ToString()
            Select ToString.Length
    

    However, ToString is not a legal name for a variable since it is a member of System.Object (why this would be the case for variables within LINQ queries but not for standard local variables, I couldn't say).

    0 讨论(0)
  • 2020-12-11 01:19

    While I can't offer details about the error, a simple workaround it:

    From x In {1, 2, 3} Let str = x.ToString() Select str
    

    For what it's worth, when you have the following line:

    Dim b = From num In {1, 2, 3} Select num.ToString("d")
    

    it is compiles and decompiles to (using Reflector, to 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));
        }
    }
    

    There doesn't seem to be any anonymous class along the way.

    0 讨论(0)
  • 2020-12-11 01:25

    I couldn't tell you exacly why VB has this ridiculousness, but the simple workaround is to put the method call in parens.

    Dim q = From x In {1, 2} Select (x.ToString())
    
    0 讨论(0)
提交回复
热议问题