locked
C# variable scope RRS feed

  • Question

  • Consider following example:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using System.Diagnostics;
    
    namespace ArrayTest
    {
        [TestClass]
        public class UnitTest1
        {
            class TestClass
            {
                public byte[] arr = null;
            }
    
            void F2(TestClass c)
            {
                byte[] arr2 = new byte[] { 0x1, 0x2 };
                c.arr = arr2;
            }
    
            void F1(byte[] arr)
            {
                byte[] arr2 = new byte[] { 0x1, 0x2 };
                arr = arr2;
            }
    
            [TestMethod()]
            public void ArrayTest()
            {
                byte[] arr1 = null;
    
                // Example 1 - array passed as a parameter
                F1(arr1);
    
                if (arr1 == null)
                    Debug.WriteLine("Standalone array is null");
                else
                    Debug.WriteLine($"Standalone array size: {arr1.Length}");
                // Example 1 output: "Standalone array is null"
    
                // Example 2 - array in the class is passed as a parameter
                TestClass c2 = new TestClass();
                F1(c2.arr);
                if (c2.arr == null)
                    Debug.WriteLine("\nArray in the class c2 is null");
                else
                    Debug.WriteLine($"\nArray size in the class c2: {c2.arr.Length}");
                // Example 2 output: "Array in the class c2 is null"
    
                // Example 3 - class is passed as a parameter
                TestClass c3 = new TestClass();
                F2(c3);
    
                if (c3.arr == null)
                    Debug.WriteLine("\nArray in the class c3 is null");
                else
                    Debug.WriteLine($"\nArray size in the class c3: {c3.arr.Length}");
                // Example 3 output: Array size in the class c3: 2
    
            }
    
        }
    }

    Why is the output in Example 3 is different from Example 1 and Example 2? I would expect it to be the same but it isn't.

    Clarification: what I mean is that both in F1 and F2 locally defined arr2 goes out of scope once we exit the function. Yet in example 3 the value persists in a class. Hope this my question clearer.
    Sunday, May 19, 2019 3:35 PM

All replies

  • I think it's because in F1 the byte[] is passed as value, which is the default for all values. So, changes to the byte[] are not visible for the caller. 

    To pass it as reference you need to do it by using the ref or out keyword. You will see that you'll get a different result.

    Here is a simple test to visualize that your oriiginal method doesn't affect the initial byte[]:

    static void F1(byte[] arr, TestClass c)
    {
        byte[] arr2 = new byte[] { 0x1, 0x2 };
        arr = arr2;
    
        if (arr == c.arr)
        {
    	Debug.WriteLine("Both variables reference the same object on the heap.");
        }
        else
        {
    	Debug.WriteLine("Each variable references its own object.");
        }
    }
    
    TestClass c2 = new TestClass();
    F1(c2.arr, c2);

    If you now use the ref keyword

    static void F1(ref byte[] arr, TestClass c)
    {
        byte[] arr2 = new byte[] { 0x1, 0x2 };
        arr = arr2;
    
        if (arr == c.arr)
        {
    	Console.WriteLine("Both variables reference the same object on the heap.");
        }
        else
        {
    	Console.WriteLine("Each variable references its own object.");
        }
    }
    
    TestClass c2 = new TestClass();
    F1(ref c2.arr, c2);
    

    you will see that both variables will reference the same object. For more details I recommend this article by Jon Skeet.

    wizend



    Sunday, May 19, 2019 4:39 PM
  • Hi JoeSchmoe115,

    Thank you for posting here.

    Since your question is more related to unit testing, I will move it to unit testing forum for suitable support.

    https://social.msdn.microsoft.com/Forums/en-US/home?forum=vsunittest&filter=alltypes&sort=lastpostdesc

    The Visual C# forum discuss and ask questions about the C# programming language, IDE, libraries, samples, and tools.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, May 20, 2019 6:28 AM