0

Looking at this Microsoft article How to: Write a Copy Constructor (C#) and also this Generic C# Copy Constructor, wouldn't it be best/safe to use a reference to the class instance than to use a plain copy of the instance ?

public class Myclass()
{
    private int[] row;
    public MyClass(ref MyClass @class)
    {
        for(int i = 0; i<@class.row.Length;i++)
        {
            this.row[i] = @class.row[i];
        }
    }
}
Community
  • 1
  • 1
Jonas
  • 1,019
  • 4
  • 20
  • 33
  • 1
    Why do you think this would be better, or safe? – Moshe Katz Jun 26 '13 at 01:31
  • 1
    If you're going to use a reserved word as a variable name, it must be preceded by `@`. Edited, but not advisable. – spender Jun 26 '13 at 01:32
  • 2
    It's probably time that you read up about what the `ref` keyword ***actually*** means, especially when used in conjunction with reference types. – spender Jun 26 '13 at 01:33
  • Reference types (e.g. `MyClass`) are always passed by reference. `ref` means you are passing a reference to the *variable*, so if you were to change `@class` to point to a different `MyClass`, the caller would see that happen to whatever variable they passed in. – Blorgbeard Jun 26 '13 at 01:39
  • 1
    Not to mention this throws out being able using the copy constructor in a variety of cases wherever `ref` isn't permitted (properties, anonymous methods, etc.) – Chris Sinclair Jun 26 '13 at 01:40
  • I think you need to take some time to review what the `ref` keyword really means. [ref keyword](http://msdn.microsoft.com/en-us/library/14akc2c7.aspx) – Instance Noodle Jun 26 '13 at 01:44
  • Another great example of `ref` ruining copy constructors are _chained_ copy constructors for inherited classes. Want to make a copy constructor for `MySubclass : MyClass` that chains into the base class? Can't do it! – Chris Sinclair Jun 26 '13 at 01:51

3 Answers3

3

What ref actually means:

void Change(SomeClass instance)
{
    instance = new SomeClass();
}
void ChangeRef(ref SomeClass instance)
{
    instance = new SomeClass();
}

Later...

SomeClass instance = new SomeClass();
Change(instance);
//value of instance remains unchanged here
ChangeRef(ref instance);
//at this line, instance has been changed to a new instance because
//ref keyword imports the `instance` variable from the call-site's scope

I can't see how this functionality would be useful with respect to a copy constructor.

spender
  • 117,338
  • 33
  • 229
  • 351
  • What if we pass something big, wouldn't it save us some space if we just pass the reference ? – Jonas Jun 26 '13 at 01:45
  • 2
    You **are** passing a reference without the ref keyword, unless you pass a value type, which is usually small enough for copying not to be an issue. You don't understand what the ref keyword means, so all your assumptions are deeply flawed. Read up on `ref` please. What economy are you hoping to make here? – spender Jun 26 '13 at 01:46
  • Yes, by definition, class instances are passed by reference. I've demonstrated quite clearly what the `ref` keyword allows you to do above. – spender Jun 26 '13 at 01:50
1

Object by nature is reference not a value type. I do not see any good reason what extra advantage you would get doing it. But yes you might get into problems because of it, consider this -

You created an object and passed it with reference to couple of classes and those classes are now having access to the address of reference itself. Now I have got all the powers to go and change the reference itself with another object's reference. If here, another class had this object it is actually working on some stale object and other classes can not see what changes are being made and you are in chaos.

I do not see any use of doing it, rather it is dangerous. It does not sounds like a OO way of writing code to me.

JustCode
  • 312
  • 1
  • 3
1

The ref keyword is used when a method should be allowed to change the location of a reference. Reference types always pass their reference into a method (but the location of the reference cannot be modified via assignment). Values types pass their value.

See: Passing Parameters

Example:

void PassingByReference(List<int> collection)
{
    // Compile error since method cannot change reference location
    // collection = new List<int>();
    collection.Add(1);
}

void ChangingAReference(ref List<int> collection)
{
    // Allow to change location of collection with ref keyword
    collection = new List<int>();
    collection.Add(2);
}

var collection = new List<int>{ 5 };

// Pass the reference of collection to PassByReference
PassingByReference(collection);

// collection new contains 1
collection.Contains(5); // true
collection.Contains(1); // true

// Copy the reference of collection to another variable
var tempCollection = collection;

// Change the location of collection via ref keyword
ChangingAReference(ref collection);

// it is not the same collection anymore
collection.Contains(5); // false
collection.Contains(1); // false

// compare the references use the default == operator
var sameCollection = collection == tempCollection; // false
Dustin Kingen
  • 20,677
  • 7
  • 52
  • 92