Solved

Passing object by value

Posted on 2006-11-08
8
179 Views
Last Modified: 2010-04-16
Hello everybody

I'm am still fairly new to C# (and OOP in general) and I've started to stumble when it comes to passing objects by value.
I've read a lot of documentation explaining what goes on when you pass an object by value, and I understand why I'm seeing the results I'm getting. But every single article I've found just falls short of offering advice on how to overcome the problems seen by people at my level of experience. So here I am....!

How can/should I get the following sample code to output "Dink Dank Do!", not "Bish Bash Bosh!"  ?

Thanks in advance.

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            myTestClass mainObject = new myTestClass();
            myProcessClass processObject = new myProcessClass(mainObject);

            Console.WriteLine(mainObject.strProperty_1);
            Console.WriteLine(mainObject.strProperty_2);
            Console.WriteLine(mainObject.strProperty_3);

            Console.Read();
        }
    }

    class myTestClass
    {
        public String strProperty_1;
        public String strProperty_2;
        public String strProperty_3;

        public myTestClass()
        {
            strProperty_1 = "Dink ";
            strProperty_2 = "Dank ";
            strProperty_3 = "Do! ";
        }
    }

    class myProcessClass
    {
        public myProcessClass(myTestClass objectPassed)
        {
            objectPassed.strProperty_1 = "Bish ";
            objectPassed.strProperty_2 = "Bash ";
            objectPassed.strProperty_3 = "Bosh! ";
        }
    }
}
0
Comment
Question by:Rusty_Adams
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +1
8 Comments
 
LVL 12

Expert Comment

by:andrewjb
ID: 17896802
Objects are passed by reference, not value.

You need a struct, not a class. Just change "class myTestClass" to "struct myTestClass" ...
0
 

Author Comment

by:Rusty_Adams
ID: 17896872
Thanks Andrew

But can I perform all the same things with a struct that I can with a class, such as have methods, hold other objects or arraylists as properties, have constructors?
0
 
LVL 12

Expert Comment

by:andrewjb
ID: 17896995
Yes etc., except.....

You can't inherit from a struct, or inherit a struct from an object. Though you can implement interfaces in a struct.
You can have constructors, but there's always a default (no parameter) constructor that just initialises the elements to zero/null/false. You can't provide your own implementation of this constructor.
0
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

 

Author Comment

by:Rusty_Adams
ID: 17897002
Does anybody know of an alternative solution?
I have an application with a large amount of classes already, and I wouldn't like to have to go through and alter them all. And I'm not convinced that I wouldn't have to rewrite much of the app if I were to change the required classes to structs.

Is there no way of making a copy of an object and passing that, so that the original object remains intact?
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 17897063
Reference types passed to functions can be always changed by this functions, this is how .NET is developed, there is nothing to do with this. I don't recommend you to replace classes with structures - structures are not used for this purpose. Structure is usually small object which contains few members of primitive types (like int), which can be copied and allocated fast - like Point. They are restricted and used only in special cases.
What is exactly your purpose? To restrict access to class members inside of function? There are two ways to make copy: using Object.MemberwiseClone Method or implementing ICloneable interface. Object.MemberwiseClone creates shallow copy, this means, if class contains references, they are not cloned.
Other way to restrict access to class instance is passing interface to function. For example, class implements some interface which allows only to read some values. Pass interface to the function instead of instance reference. I don't recommend you to clone objects - this is not efficient.
0
 

Author Comment

by:Rusty_Adams
ID: 17897171
Thanks Alex

This problem came up in the following situation:

I have a form called frmUser_Group.  In this form a use an instance of another class, clUser_Group.  clUser_Group has properties for holding some info about the group. It also holds an ArrayList containing instances of clUser  (a group can have many users, you get the picture).
On this form I have a button labelled "Add/Remove" users. This button opens up a second form which I'm opening up as a dialog. When I open the dialog I pass through the arrayList property of the clUser_Group object in the constructor.

frmUser_Group_AddRemoveUsers frmAddRemove = new frmUser_Group_AddRemoveUsers(_oUser_Group.arrUser_Group_Xrefs);
frmAddRemove.StartPosition = FormStartPosition.CenterParent;
frmAddRemove.oParentForm_instanceRef = this;
frmAddRemove.ShowDialog(this);

In the constructor of the second form I then use the array passed through to fill another array, which I though meant I was working on a copy.

public frmUser_Group_AddRemoveUsers(ArrayList arrUser_Group_Xrefs_Passed)
            {
                InitializeComponent();

                this.arrUser_Group_Xrefs = arrUser_Group_Xrefs_Passed;

                PopulateForm();
            }

When the user adds and removes users from the group in the dialog, it's also adding and removing from the parent form. This caused a problem if the user changes his/her mind and simply closes the dialog. The parent form then still reflects the changes they made but chose not to keep.

I wanted the array in the dialog to be seperate, and pass it back somehow when the user presses ok, or simply ignore it if the user presses cancel or closes the dialog.

I've never heard of interfaces.
Is this a suitable situaltion for interfaces?
0
 
LVL 29

Assisted Solution

by:Gautham Janardhan
Gautham Janardhan earned 100 total points
ID: 17897241
public class TestClonnable :ICloneable
      {
            #region ICloneable Members

            public object Clone()
            {
                  //u will have to develop ur copy / clone logic inside here;      
                                }

            #endregion

      }

and then u pass ur object when u want to pass value as object.Clone()
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 120 total points
ID: 17897523
Cloning and interfaces is general way to restrict reference type to be changed by function. In your case, you have specific problem with ArrayList, which can be solved by creating copy of ArrayList:

ArrayList copyList = new ArrayList();

foreach ( YourClass c in _oUser_Group.arrUser_Group_Xrefs )  // YourClass is type which you keep in the list - set here real name
    copyList.Add(c);

frmUser_Group_AddRemoveUsers frmAddRemove = new frmUser_Group_AddRemoveUsers(copyList);

if ( frmAddRemove.ShowDialog(this) == DialogResult.OK )
{
    _oUser_Group.arrUser_Group_Xrefs = copyList;
}

Notice that if you keep reference types in ArrayList, they are not cloned - only references to them are copied. Decide whether this is OK for you.

General consideration: you need to read about reference and value types and understand how they work, what does this mean passing reference type by value and by reference, what is cloning, shallow copy - basic .NET concepts. This is necessary to design correctly such algorithms.

If you have C++ knowledge, reference is like pointer. Actually, this is smart pointer with reference counter.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Name Space error VS2015 1 37
Input parameteres to DragOver 2 38
C# class library debugging - Breakpoint will not hit. 8 34
Build a string of emails from a gridview 2 19
Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question