How to Use a Value Type Object as a Reference Type

Is object a reference type or value type?

It is a reference type

Doing an example with string isn't very illuminating, because string is also a reference type (as is SampleClass, obviously); your example contains zero "boxing".

if object is reference type then why obj2 value is still "OldString"

Why wouldn't it be? When you create a new string, that doesn't change old references to point at the new string. Consider:

 object obj1 = "OldString";
// create a new string; assign obj1 the reference to that new string "OldString"

object obj2 = obj1;
// copy the reference from obj1 and assign into obj2; obj2 now refers to
// the same string instance

obj1 = "NewString";
// create a new string and assign that new reference to obj1; note we haven't
// changed obj2 - that still points to the original string, "OldString"

How to use a value type object as a reference type?

I would typically recommend solving this with closures. It's more powerful and safer. For example:

let append: (Object) -> Void

switch someValue {
case .thisArray: append = { thisArray.append($0) }
case .thatArray: append = { thatArray.append($0) }
case .anotherArray: append = { anotherArray.append($0) }
}

append(object)

(It would be ideal here to just say append = thisArray.append, but you can't do that in Swift today. It's a "partial application of a mutating function" and that's not currently legal.)

How to Find the Object is a Value Type OR Reference Types in C#

You can use properties IsValueType and IsClass on Type:

if(param.GetType().IsValueType)
{
// param is value type
}
else if(param.GetType().IsClass)
{
// param is reference type
}

Value Type, Reference Type and Boxing

is it accurate to say that a value type such as int is also a reference type?
…Or is it more accurate to say that a value type can be a reference type through the process of boxing.

Neither is accurate. int is a value type, period. It is not "also a reference type". And when boxed, it's not magically changed to be a reference type. The System.Object that contains it is a reference type, but inside is still the value of the value type int.

Is i holding the value of 10, or is it an object holding a reference to the value of 10?

See above. i has the type int, which is a value type, and so the variable contains the value you've assigned to it, 10.

See also What is the difference between a reference type and value type in c#?

Value and Reference types confusion

This has nothing to do with the type of the field you are changing. What is relevant here is indeed just the kind of the parent type:

IntHolder first = new IntHolder();
IntHolder second = first;

Depending on the kind of IntHolder this has two different effects:

For value types (struct), this creates a copy. The data of the value type object lives with the object, so all of it is copied. It’s kind of equivalent to this:

IntHolder second = new IntHolder();
second.number = first.number;
// and all other fields (visible or not) are copied too

This means that an assignment to a field of the copied value type will overwrite that value without affecting the original object. It’s like how a local variable behaves:

var x = 5;
var y = 2;
y = 3; // this does not change x

However, when the type is a reference type, the assignment second = first just copies the reference. The underlying object where the values are kept are the same for both. So changes to either object affect the other—because there is no “other”: it’s the same object that’s just being referenced by two separate variables.


To answer the follow-up questions from the comment:

How do I need to imagine it that an int variable is a value type and string is a reference type? I mean, so the int variable directly contains the number and the string variable is just like a pointer to a storage location of the string object?

Yes, that’s exactly it. The value of a reference is basically just a pointer to the memory where the object actually is, while the value of a value type is the whole object itself.

That’s why e.g. having a value type as the parameter to a method means that when the method is called, the whole value type object is copied into the stack for the execution of the method.

A type being a value type does not mean that its members will all be value types too though. For example, the actually stored value of a string member inside a value type is still a reference to the string object. Similarly, the actual memory for a reference type will contain the actual value for value types, and references to other memory locations for reference types.

If the parent type always matter more than the objects types, what can I use the type of int and string for?

There is nothing that matters more than another. An object being a value or a reference type has only implications on how that object is stored. For members of the object, this is evaluated completely separately.

Is it possible if you just have one class and a bunch of variables to set some of them just as a reference to another variable, for example int variables.

You cannot have a reference pointer for a value type, like you could have in C, no. But you can have references to fields which allow you to mutate the value of fields that are of a value type. For example:

class Test
{
private int field;

public void ShowExample()
{
// set the value
field = 12;

// call the method and pass *a reference* to the field
// note the special syntax
MutateField(ref field);

// the field, which is a value type, was mutated because it was passed as a reference
Console.WriteLine(field == 4);
}

private static void MutateField(ref int value)
{
value = 4;
}
}

value type reference type object in javascript

JavaScript Objects (and by extension: arrays, regexes, dates, non-primitive strings/numbers/booleans etc.) equality and assignment are reference based:

{a:'a'} == {a:'a'} // false

But:

var myObject = {a:'a'};
var myObject2 = myObject;

myObject == myObject2 // true

Furthermore:

myObject.b = 'b';

console.log(myObject2.b); // Logs: "b"

Can I treat a reference type as a value type here, or do I need to clone?

Well you don't need to use serialization, but you do need to create separate objects. Quite how deeply you need to clone will depend on the type - for example, you don't need to clone any immutable types. (The more immutability you can introduce into your code, the easier this becomes.)

There's no concept of "treating a reference type as a value type", but even if there were it would only naturally perform a shallow clone anyway, so you wouldn't be much better off.

How will an object with a value type and reference type be stored in .NET?

Eric Lippert just wrote about this:

It is simply false that the choice of whether to use the stack or the heap has anything fundamentally to do with the type of the thing being stored.

The true story is:

"in the Microsoft implementation of C# on the desktop CLR, value types are stored on the stack when the value is a local variable or temporary that is not a closed-over local variable of a lambda or anonymous method, and the method body is not an iterator block, and the jitter chooses to not enregister the value."

Most importantly, he stresses that you simply should not care where a type lives. You should care where things of a certain lifetime live.



Related Topics



Leave a reply



Submit