views:

137

answers:

4

I am a bit new to C# and was just wondering if there is a list of classes (commonly used) which are by default passed as copy. How can I identify them?

I know the basic basic object types — int, uint, float, strings, ... — are passed by copy.

+6  A: 

All types, by default, are passed by value. The difference between value types (struct) and reference types (class) is that for value types a copy of the value is passed to the method, whereas for reference types, only a reference is passed.

See MSDN for more details.

Also, don't confuse the notion of value/reference types, and the notion of passing parameters by value or by reference. See this article by Jon Skeet for details

Thomas Levesque
No, both are passed by value. In the case of references though it's the reference which is passed by value, not the object.
JaredPar
Indeed, that was badly phrased... I fixed it
Thomas Levesque
-1, this statement is simply wrong and jaredpar is correct.
Ben Robinson
Removed my -1, as you corrected your answer.
Ben Robinson
+2  A: 

In general,

  • value types, which includes native types (int, float, ...) as well as structs are passed "by copy" (as you put it), whereas in

  • reference types, which includes classes, only a reference is copied instead of the complete object.

Note, though, that string is not passed "by copy"! It's a reference type, but since it's immutable, it behaves similar to a value type.

Note that the ref keyword can be useful in both cases: In the case of value types, it means that the value is copied back. In the case of reference types, it means that the reference can be changed (i.e., that you can assign the variable to a new object rather than just changing the properties of the object.)

Heinzi
Why the downvote?
Heinzi
-1 all types are passed by value in c# unless you use the ref or out keywords. It just happens that with reference types the value is the reference. e.g. if you pass a reference type into a method and set it to null in the method, if doesn't null out the variable you passed in only the COPY in the method.
Ben Robinson
@Ben: Exactly, that's why I avoided the phrase "by reference" in the second case and explicity mentioned the use of the ref keyword. I've reworded my answer to make this clearer.
Heinzi
removed my -1 becuase you updated your answer to be more clear.
Ben Robinson
@Ben: Thanks (for removing the -1 as well as for the feedback).
Heinzi
+4  A: 

In C# / .Net objects can either be classified as value or reference types [1]. Value types are any type which derive from System.ValueType and are defined in C# with the struct type declaration. These are passed by copy / value.

Reference types are types which do not derive from System.ValueType and are defined in C# with the class keyword. Identifiers to instances of reference types are known as references (similar to pointers). These are also passed by value by default but only the reference is passed not the whole object.

Your question also mentioned that string instances are passed by copy. String in .Net is a reference type (derives directly from System.Object) and hence is not passed by full copy.

[1] Pointers may merit their own class here but I'm ignoring them for this discussion.

JaredPar
Thank you, the System.ValueType inheritance in between helped me understand this!
tvr
+1  A: 

Note also that struct objects can include reference types:

struct Currency
{
    int Amount {get;set;} // is referenced by value (copy)
    string Code {get;set;} // is referenced by reference
}

When your use that struct like this:

var obj1 = new Currency{Amount = 1, Code = "USD"};
var obj2 = obj1;

Then

object.ReferenceEquals(obj1.Code, obj2.Code); // false - string is reference type, but used inside value type

If you have declared Currency as class then references to Code were the same.

Petr Kozelek