ITSWITCH: #1

Is There Something Wrong In This Code Here

UPDATE: as several readers pointed out there was compile error in the code what was being displayed.  The line “String value = string[i]” was showing up as “String value = string”.  I’m not sure why; but throwing some spaces between the i and the square brackets seems to have solved it.

In the following class, is there something wrong with either InitializeOne or InitializeTwo (hint, it has nothing to do with compile errors and I’m ignoring performance differences)?

    public class TestClass
    {
        private List<MethodInvoker> delegates;
 
        private static void ProcessText(String text)
        {
            Trace.WriteLine(text);
        }
 
        public void Run()
        {
            foreach(MethodInvoker invoker in delegates)
            {
                invoker();
            }
        }
 
        public void InitializeOne(String[] strings)
        {
            delegates = new List<MethodInvoker>(strings.Length);
            for (int i = 0; i < strings.Length; ++i)
            {
                String value = strings[ i ];
                delegates.Add(delegate { ProcessText(value); });
            }
        }
 
        public void InitializeTwo(String[] strings)
        {
            delegates = new List<MethodInvoker>(strings.Length);
            foreach(String value in strings)
            {
                delegates.Add(delegate { ProcessText(value); });
            }
        }
    }

Answer on Monday.

5 thoughts on “ITSWITCH: #1”

  1. I am assuming that this line:
    String value = strings;

    Should actually be:
    String value = strings[i];

    And yeah, there is a difference. :-) But, I have seen this issue numerous times before, so I won’t give it away here.

    Igor

  2. Well for one you can not do this:

    String value = strings;

    I think what you mean is this:

    String value = strings[i];

    But this is not what you are getting at.

    So the difference between InitializeOne() and InitializeTwo() is the way you iterate through the String array and the way you insert the “value” object into the List. Consider we are passing in a String array consisting of {“One”, “Two”, “Three”} into both methods. Inside InitializeOne() the values “One”, “Two”, “Three” will get stored in the List but for InitializeTwo() the values “Three”, “Three”, “Three” will get stored. This is because the way “value” was inserted into the List. In InitializeOne() “value” get created on the heap since behind the scene we are new-ing a new String variable. In InitializeTwo() value is being used as a reference and hence only the last reference will be added to the List. You could still use a foreach loop to insert items into your List but you need to new them.

  3. I imagine this should be familiar to most of your readers … some more fun ones:

    public static void InitializeThree(String[] strings)
    {
    delegates = new List(strings.Length);
    foreach (var value in strings)
    {
    var v = value;
    delegates.Add(delegate { ProcessText(v); });
    }
    }

    public static void InitializeFour(String[] strings)
    {
    delegates =
    strings.Select(s => () => ProcessText(s)).ToList();
    }

    Or, if you must use query syntax …

    public static void InitializeFive(String[] strings)
    {
    delegates =
    (from s in strings
    select ((MethodInvoker)(() => ProcessText(s)))).ToList();
    }

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>