質問

As far as I know Class and Object are reference type.

I have below method to Change the Value

public void ChangeValue(MyClass classobj)
{
    classobj.Number = classobj.Number*2;
}

I invoke the method to double the value

var myClass=new MyClass();
int myNumber = 10;
myClass.Number = myNumber;
ChangeValue(myClass);

And it will be return 20 which is fine as you can interpret it as when you make object of your class then it pass reference to method and it will update the reference values.

but my question is why its not happening for Object type. In other words why when I make object and assign some value to it like below

 object myObject = new object();
 string sometext  = "Some object value";
 myObject = sometext;
 ChangeValue(myObject)

it wont change the value after executing the method

public void ChangeValue(object objectValue)
{
    objectValue = null;
}

I know the parameter of methods are value types but can not understand it have different behavior for two reference type.

役に立ちましたか?

解決 3

It's not a different behavior, you're doing different things

This will work exactly as your object example:

    public void ChangeValue(MyClass classobj)
    {
        classobj = null;
    }

And this will work as your first example(assuming you will pass MyClass instance):

   public void ChangeValue(object objectValue)
    {
        ((MyClass)objectValue).Number *= 2;
    }

What realy happens here is that when you are assigning parameter (not a property or field of parameter) you are only changing that parameter's value. Original value and variable in calling code stay intact.

The same happens here:

MyClass a = new MyClass();
MyClass b = a;
a = null;
// b still contains the value created in the first line

Simply speaking, reference variables hold the pointer (memory address) of the actual value. By changing variable's value, you are making it point to different object or null. But when you are doing a.field=2 this means you are taking the object a is referencing to and changing it's field member value.

他のヒント

You're actually doing two different things here. Object and your MyClass are indeed both reference types, which means you pass a reference to the actual object into the ChangeValue method. However, the reference that you see inside the method is a copy of the reference the caller holds. They point to the same object, so when you manipulate the object in the method the caller of the method can see your changes, but changes to the actual reference inside the method only affect the method itself.

In an attempt to summarise, objects are passed by reference, but those references are passed by value.

In your method

public void ChangeValue(object objectValue)
{
    objectValue = null;
}

What you're actually doing is reassigning the reference objectValue, and that reference is a copy of the reference called myObject which the caller has. Because the method only has a copy, it can't affect the caller's reference at all.

There is a way to make this work, you have to pass the reference by reference. Which always gives me a headache, but that's what the ref keyword is for.

public void ChangeValue(ref object objectValue)
{
    objectValue = null; // this is the SAME reference as the caller has, so the caller will see this change
}

However then it also has to be called that way:

ChangeValue(ref myObject);

so that it's obvious at the call site that it might come back pointing to a different object. It's important to know that, as you might still have things relying on the old value and end up in a horrible confused mess if references were pointing to different objects unexpectedly.

You pass the objectValue to the ChangeValue(object objectValue) by value and this value is a reference. Then you change this value, but not the value of the myObject.

You have to pass it as ChangeValue(ref object objectValue) to actually pass the value of reference by reference.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top