CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Aug 2012
    Posts
    3

    Problem related to the use reference

    Hello everybody,
    I am new on this forum. I register today as I started developing an application in c# and I am having some problems...
    I would thus appreciate advices from most experimented developers

    Here is the kind of code parts where I have some trouble:
    Code:
        class object1
        {
            public ArrayList mChiffres;
    
            public object1(ArrayList chiffres)
            {
                this.mChiffres = chiffres;
            }
        }
    
        class Program
        {
            int[] numbers1 = new int[9] {1,2,3,4,5,6,7,8,9};
            ArrayList list = new ArrayList();
    
            public void method1(int i, ref ArrayList listMain)
            {
                if (numbers1[i] < 9)
                {
                    listMain.Add(numbers1[i]);
                }
                else
                {
                    object1 o1 = new object1(listMain);
                    list.Add(o1);
    
                    listMain.Clear();
                }
            }
    
            static void Main(string[] args)
            {
                int i=0;
                ArrayList listMain = new ArrayList();
    
                while(i<10)
                {
                    method1(i, ref listMain);
                    i++;
                }
            }
        }
    I noticed that when I am clearing the ArrayList "listMain". I am also deleting the value in the object1 "o1" 's field... I suspect it to be related to my use of reference. But can't find a solution to that problem. Any help appreciated !

    btw have to use reference and a separate method1 (for the curious it's just that I am planning to have a recursive call to method1 inside method1 later)
    Thank you in advance

  2. #2
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Problem related to the use reference

    You don't need to use the ref keyword, since arrays are reference types, which means they are passed by reference anyway - so the parameter will point to the same list. That's the reason why your o1 object ends up empty - it's the same list. Now, your else branch will only be true for numbers1[i] == 9, when, I suppose, you are trying to add a list of numbers 1-8? You can go two ways with this: either create an empty list in the constructor of object1, provide a way to get the list (e.g. via a property), and then call Add() on it for each number in listMain, or make a copy of listMain, and pass that. You'll have to provide a way to retrieve the data in mChiffres anyway, unless you just wanna use it internally in the object1 class.

    A tip: instead of ArrayList, better use the generic List<T>, where T is a type parameter (List<int> for ints, List<object1> for instances of object1), so that the data doesn't have to be stored as object type. BTW, "object1" is not exactly the best name for a class... Especially because "objects" usually designate instances of a class. Try finding something more descriptive.
    Also, in C#, most people follow this naming convention: camelCase for private member variables and function parameters, PascalCase for public class, method and property names. Makes it easier for others to read and understand your code.

  3. #3
    Join Date
    Aug 2012
    Posts
    3

    Re: Problem related to the use reference

    Thanks for the answer it is very informative. I did not know ArrayList were reference defined.
    As soon as I reach a computer with visual studio, I will try to create a copy arraylist in the constructor of my object1 like that:

    Code:
        class object1
        {
            public ArrayList mChiffres;
    
            public object1(ArrayList chiffres)
            {
                mChiffres   = new ArrayList();
                mChiffres.AddRange(chiffres);
            }
        }
    I will be careful to my variable names in the future.
    Cheers

  4. #4
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Problem related to the use reference

    That's right. But, a word of caution. As I already hinted, C# has two kinds of types - reference types (classes), and value types (structs). Reference types are kind of like smart pointers, so if you want to create a copy, you need to explicitly call a method that creates one (defined by you for your own types, or an existing one for 3rd party types). You can find out the type of each variable by simply hovering your mouse pointer over it in the IDE; it will also say if it's a class or a struct. And of course, you can always check the MSDN documentation for the type.

    Now, arrays, lists and such, reference types themselves, can hold any other kind of type. Elements can be structs or classes. If you were using the generic List<int>, you would get the appropriate pass-by value behavior for methods like AddRange - since int is a value type, a copy would be passed and stored in the array. If you were using List<object1> (pass-by-reference semantics), and passed in a bunch of elements also contained in another list or an array, or some other collection, the two collections would end up pointing to the same elements (they would share elements). Clearing one (or inserting/removing elements of one) would not affect the other, but if you changed a property of an element in a list, both lists would reflect this change (since they share the element).
    Code:
    listA:                                     listB:
    [0]---------------> [object0] <---------------[0]
    [1]---------------> [object1] <---------------[1]
    [2]---------------> [object2] <---------------[2]
    [3]---------------> [object3] <---------------[3]
    [4]---------------> [object4] <---------------[4]
    
    
    // operations on the list affect only one list
    
    listA:                     listB.Remove(object3):
    [0]---------------> [object0] <---------------[0]
    [1]---------------> [object1] <---------------[1]
    [2]---------------> [object2] <---------------[2]
    [3]---------------> [object3]                  x 
    [4]---------------> [object4] <---------------[3]
    
    
    // Operations on elements affect both:
    listA[4].Message = "hello";
    
    string msg = listB[3].Message;  // msg is "hello"
    Sometimes, this is what you want, sometimes it's not. If not, than you need to create a copy of each element before you pass them in, either one by one, or, if the collection supports it, by copying the entire input collection.

    Since you're using the non-generic ArrayList class, which stores everything as object references, value types get "boxed" into an object instance (object is a reference type), so I suspect that this means that ArrayList must use pass-by-reference semantics, so the elements are shared, but I didn't check. This wouldn't be a problem if the object1 constructor accepted, say, an array of integers (int[]) or a List<int>, since in that case, each element would be retrieved by value before it would be stored in mChiffres. But since it's a collection of object-s, then I think the elements will be shared.

  5. #5
    Join Date
    Aug 2012
    Posts
    3

    Re: Problem related to the use reference

    Thank's for the detail.
    Good evening

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured