Possible pedantic dickweedery in .NET arrays



  • As a side project at work, I'm rewriting a desktop application in C# that pulls large arrays of bytes from a database, converts them to floating-point numbers, and displays them in a graph. For some reason this application was originally written in LabVIEW even though it runs on a Windows PC and takes advantage of zero LabVIEW low-level-coding features. Also I hate LabVIEW on principle, hence the rewrite. The bytes in the database are stored in BLOBs in big-endian order, but since .NET's BitConverter works in little-endian it is necessary to reverse the arrays before performing the conversion.



    So I was happily coding along until the point where I hooked the arrays of floating point numbers up to graphs and saw that the data was haywire. It seemed to range between -infinity and infinity with no pattern whatsoever. I looked at the same dataset using the LabVIEW program and it looked correct, so the problem has to be somewhere in the C# application. Commence digging, looking through old design documents, etc....



    Fast forward a few weeks to today when I discovered an online example of a similar situation which uses Array.Reverse(arg) instead of arg.Reverse() to reverse the byte order. Expecting no difference, I made the change and recompiled.



    The data displayed correctly. WTF. Really?



    According to the documentation, Array.Reverse(arg) "Reverses the sequence of the elements in the entire one-dimensional System.Array" whereas arg.Reverse() "Inverts the order of the elements in a sequence". Those both read the same to me. And so I turn it over to those accused of being pedantic dickweeds on this forum: is there any reason to expect that these two functions would do something different? In other words, WTF?



  • I don't know C#, but I have been speaking English natively for more than 50 years; those two say the same thing to me.

     



  •  What are the return values? Perhaps Array.Reverse returns null and reverses the array in-place, and arg.Reverse() returns a new reversed collection without affecting the original array. If arg.Reverse() is from the System.Linq namespace, that's probably what's going on.



  • Here's the documentation: http://msdn.microsoft.com/en-us/library/bb358497.aspx

    Reverse() is an extension method of Enumerable.  Probably because it is a part of the Linq namespace, it was designed to use deferred execution.  You have to call GetEnumerator() (normally by use of a foreach loop) in order to get the reversed elements.  If Visual Studio didn't automatically include "using System.Linq;" at the top of every new class file, there would be less confusion like this.



  • I like to put .ToList() or .ToArray() on the end of Linq methods if I need to avoid deferred execution.



  • And of course there are "tutorials" like this one: http://www.dotnetperls.com/array-reverse where the author claims to be showing you a simplified version of array reversal.  Unfortunately, the foreach loop he's using for display purposes just happens to make this example work, probably inadvertently.

     



  • And this is what happens when I don't RTFM thoroughly. :P Thanks for the replies.



  • @mott555 said:

    I like to put .ToList() or .ToArray() on the end of Linq methods if I need to avoid deferred execution.

     

    How about .ToList().ToArray() to be doubly sure?



  • @frits said:

    @mott555 said:

    I like to put .ToList() or .ToArray() on the end of Linq methods if I need to avoid deferred execution.

     

    How about .ToList().ToArray() to be doubly sure?


    public List<int> ReverseList(List<int> numbers)

    {

        return numbers.Reverse().ToList().ToArray().Skip(0).ToList().ToArray().Take(numbers.Count).ToList().ToArray().Where(i => true == true).ToList().ToArray().Select(i => i).ToList().ToArray();

    }

     



  • I'm afraid that won't compile; the return type is List<int>, and you're trying to return an int[] :)



  • @ekolis said:

    I'm afraid that won't compile; the return type is List<int>, and you're trying to return an int[\] :)

    Shove another toList() on the end and ship it!




  • @DaveK said:

    @ekolis said:

    I'm afraid that won't compile; the return type is List<int>, and you're trying to return an int[\] :)

    Shove another toList() on the end and ship it!


     

    Can you navigate it with the arrow keys?

     



  • @dhromed said:

    @DaveK said:

    @ekolis said:

    I'm afraid that won't compile; the return type is List<int>, and you're trying to return an int[\] :)

    Shove another toList() on the end and ship it!


     

    Can you navigate it with the arrow keys?

     

    It uses QWOP for everything!

     


Log in to reply