Click here to Skip to main content
15,897,151 members
Articles / Programming Languages / C#
Article

C# Parameter: Pass object by value, The copy constructor

Rate me:
Please Sign up or sign in to vote.
1.73/5 (5 votes)
5 Jul 20062 min read 146.2K   13   4
Work around: C# Parameter: Pass object by value, The copy constructor
Introduction

When we writing our code, we need quite often to pass a parameter. There are different type of variables can be passed(value type, reference type, immutable reference types), and they can be pass as different kind of parameters(value parameter, reference parameter, output parameter, parameter array). We know C# parameters are default passed by value. But note, for a reference type variable, more often people see that as passed by reference by default. In fact when we say an object is passed by refernce by default what actually happen is "that object reference is passed by value by default" (detailed explanation please see an article here: http://www.yoda.arachsys.com/csharp/parameters.html).

Content

This sounds extramely confusing, especially when i first came to this area. Now i'll try to show this by a small example.
Here we have an int as value type:

C#
public void InternalMagic(int x)
{
   x+=100;
}

int i=100;
InternalMagic(i);
Console.WriteLine(i);
// Output will be '100' -- easy, little magic !-_-

Here we have an object of our own type:

C#
public class Person
{
   public string Name;
   public string Gender;
}

public void InternalMagic(Person x)
{
   Person y=x;
   y.Name="One Girl";
   y.Gender="F";
} 
Person p=new Person();
p.Name="One Boy";
p.Gender="M";
InternalMagic(p);
Console.WriteLine(String.Format("{0} {1}", p.Name, p.Gender));
// Output will be 'One Girl F'


Here the inside and outside variable reference to the same Person object. It is because the reference of the outside variable passed into the fuction, by value(easier to understant when consider the passed value is similar to a "pointer value").
Therefore, when passing a reference type parameter to a function even we didn't set the parameter as ref, the operation still can affect the underlying object.
But in some case we do want to pass an object by value. Now consider the below example:

C#
public class Product
{
   public string Name;
   public string Color;
   public string Category;
}

public Product Produce(Product sample)
{
   Product p=sample;
   p.Category="Finished Product";
   return p;
} 
Product sample=new Product();
sample.Name="Toy";
sample.Color="Red";
sample.Category="Sample Product";
Product p=Produce(sample);
Console.WriteLine(String.Format("Product: Name={0}, Color={1}, Category={2}", p.Name, p.Color, p.Category));
Console.WriteLine(String.Format("Sample: Name={0}, Color={1}, Category={2}", sample.Name, sample.Color, sample.Category));
// Output:
// 'Product: Name=Toy, Color=Red, Category=Finished Product'
// 'Sample: Name=Toy, Color=Red, Category=Finished Product'

This is not what we intented to do. We want keep the sample with a category of 'Sample Product'. To copy an object's properties we need to explicitly set every field. The copy constructor is a good way to do this. Now modify the code as below:

C#
public class Product
{
   public string Name;
   public string Color;
   public string Category;

   public Product(Product o)
   {
      this.Name=o.Name;
      this.Color=o.Color;
      this.Category=o.Category;
   } 
   // Note we need to give a default constructor when override it
   public Product()
   {
   }
} 
public Product Produce(Product sample)
{
   Product p=new Product(sample);
   p.Category="Finished Product";
   return p;
}
C#
Product sample=new Product();
sample.Name="Toy";
sample.Color="Red";
sample.Category="Sample Product";
Product p=Produce(sample);
Console.WriteLine(String.Format("Product: Name={0}, Color={1}, Category={2}", p.Name, p.Color, p.Category));
Console.WriteLine(String.Format("Sample: Name={0}, Color={1}, Category={2}", sample.Name, sample.Color, sample.Category));
// Output:
// 'Product: Name=Toy, Color=Red, Category=Finished Product'
// 'Sample: Name=Toy, Color=Red, Category=Sample Product'

In this way we apparently pass an object by its value. In fact we just create a new object as a copy of that oject with the copy constructor.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 1 Pin
Anurag Sarkar27-Aug-12 10:45
Anurag Sarkar27-Aug-12 10:45 
GeneralYes ICloneable is a greate way to do this. Pin
Zero Wang6-Jul-06 19:49
Zero Wang6-Jul-06 19:49 
i tried ICloneable implementation and that just works very nicely.
here i also found an article in codeproject by Amir Harel, describing a useful way to do a 'deeper clone' automatically:
http://www.codeproject.com/csharp/cloneimpl_class.asp[^]
GeneralClone and ICloneable Pin
Marc Clifton6-Jul-06 3:38
mvaMarc Clifton6-Jul-06 3:38 
GeneralRe: Clone and ICloneable Pin
Ravi Sant26-Apr-11 0:11
Ravi Sant26-Apr-11 0:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.