none
Lambda expression RRS feed

  • Question

  • Hi All,

    Below are the code that used to add the size of a few files into an ArrayList object:

    ArrayList alFileSize = new ArrayList();
    foreach (DataGridViewRow dr in dgv1.Rows)
    {
    	FileInfo fi = new FileInfo(dr.Cells[1].Value.ToString());
            if (!File.Exists(dr.Cells[1].Value.ToString()))
            {
            	txtResults.Text = "Error found on " + dr.Cells[0].Value.ToString();
                    txtResults.BackColor = Color.Red;
                    break;
    	}
            else
            {
            	dr.Cells[2].Value = fi.Length;
                    alFileSize.Add(fi.Length);
                    dr.Cells[3].Value = fi.LastWriteTime;
    	}
    }

    And then i m using the Lambda expression to find out are the file size the same for those file size added into the ArrayList:

    var allSame = Array.TrueForAll(alFileSize.ToArray(), x => x == alFileSize.ToArray()[0]);
    if (allSame == true)
    	txtResults.BackColor = Color.Green;
    else
    	txtResults.BackColor = Color.Red;

    By physicallly looking into the size of those files, i can be told that they are all the same, hence, below statement should return true: Array.TrueForAll(alFileSize.ToArray(), x => x == alFileSize.ToArray()[0]), but it returns false.

    strangely, when i physically add (hard coded) the file size into the ArrayList object, like below:

    ArrayList al = new ArrayList();
    al.Add("19521729");
    al.Add("19521729");
    al.Add("19521729");
    al.Add("19521729");
    al.Add("19521729");

    and then i m using the same Lambda expression, as below:

    var allSame_1 = Array.TrueForAll(al.ToArray(), x => x == al.ToArray()[0]);
    if (allSame_1 == true)
    	txtResults.BackColor = Color.Green;
    else
        	txtResults.BackColor = Color.Red;

    as expectd, this statement returns true: Array.TrueForAll(al.ToArray(), x => x == al.ToArray()[0])

    Can someone in here tell why the first Lambda expression returns false, whereas the second one returns true.


    • Edited by AndieDu Monday, January 13, 2014 3:32 AM
    Monday, January 13, 2014 3:27 AM

Answers

  • The second lambda is testing an array of strings ("19521729" is a string, because it's in quotes), whereas the first is testing an array of long integers.

    The problem is that, either way, the ArrayList.ToArray() method returns an array of objects, not an array of a particular type. This means that the "==" test will be true if the objects are the same, not their values.

    Try this...

             // make sure we are dealing with longs, not objects.
             long[] longArray = (long[])alFileSize.ToArray(typeof(long));
             var allSame = Array.TrueForAll(longArray, x => x == longArray[0]);

    • Marked as answer by AndieDu Monday, January 13, 2014 6:45 AM
    Monday, January 13, 2014 4:29 AM
  • Don't use ArrayList you are running into equality issues with boxed longs.  Use the far superior generic equivalent List<long>
    var fileSizes = new List<long>();
    foreach (var dr in dgv1.Rows)
    {
       var fi = new FileInfo(...
       if (File.Exists(dr.Cells[1].Value].ToString()))
       {
          dr.Cells[2].Value = fi.Length;
          fileSizes.Add(fi.Length);
          dr.Cells[3].Value = fi.LastWriteTime;
       }
       else
       ...
    }
    
    var allSame = fileSizes.All(x => x == fileSizes[0]);
    

    (in fact, never use ArrayList ever again in your life. List<T> has been around since .Net 2.0)

    Paul Linton

    • Marked as answer by AndieDu Monday, January 13, 2014 6:45 AM
    Monday, January 13, 2014 4:47 AM

All replies

  • The second lambda is testing an array of strings ("19521729" is a string, because it's in quotes), whereas the first is testing an array of long integers.

    The problem is that, either way, the ArrayList.ToArray() method returns an array of objects, not an array of a particular type. This means that the "==" test will be true if the objects are the same, not their values.

    Try this...

             // make sure we are dealing with longs, not objects.
             long[] longArray = (long[])alFileSize.ToArray(typeof(long));
             var allSame = Array.TrueForAll(longArray, x => x == longArray[0]);

    • Marked as answer by AndieDu Monday, January 13, 2014 6:45 AM
    Monday, January 13, 2014 4:29 AM
  • Don't use ArrayList you are running into equality issues with boxed longs.  Use the far superior generic equivalent List<long>
    var fileSizes = new List<long>();
    foreach (var dr in dgv1.Rows)
    {
       var fi = new FileInfo(...
       if (File.Exists(dr.Cells[1].Value].ToString()))
       {
          dr.Cells[2].Value = fi.Length;
          fileSizes.Add(fi.Length);
          dr.Cells[3].Value = fi.LastWriteTime;
       }
       else
       ...
    }
    
    var allSame = fileSizes.All(x => x == fileSizes[0]);
    

    (in fact, never use ArrayList ever again in your life. List<T> has been around since .Net 2.0)

    Paul Linton

    • Marked as answer by AndieDu Monday, January 13, 2014 6:45 AM
    Monday, January 13, 2014 4:47 AM
  • great, thanks a lot!
    Monday, January 13, 2014 6:46 AM
  • great, thanks a lot
    Monday, January 13, 2014 6:46 AM