object is really reference type? - c#

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.

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.

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.

Related

Returning a private field by ref from a get only property

I have been messing around with structs. I have looked for an example of this but have not found anything.
struct TransformComponent
{
public int X { get; set; }
}
class Foo
{
private TransformComponent _transform;
public ref TransformComponent Transform
{
get { return ref _transform; }
}
}
class Bar
{
Foo testFoo = new Foo;
void TestMethod()
{
testFoo.Transform.X = 5;
}
}
This compiles and works as you would assume it does.
Is there something wrong with doing this that I am not seeing?
The reason why this is interesting to me is that as TransformComponent being a Value Type rather than a Reference Type it would be stored in memory next to the Foo object correct? Rather than possibly somewhere else in memory if it was a Reference Type?
Edit:
After reading the post I realize my question might not have been clear.
Will the _transform be stored next to the Foo object in memory since it is a Value Type and a field of the class?
Edit 2:
Reading the answer, it is clear that the _transform Member is getting allocated along side the Foo instance on the Heap.
If I am not mistaken, I am removing one level of address reference by doing it this way correct?
If I switched TransformComponent to a Reference Type the _transform Member would be a reference to the object allocated in the Heap rather than a reference to the Value itself correct?
Edit 3:
I need to look into how things are allocated more. Thank you to everyone who participated, for your time.
as Transform is part of Class Foo, it get stored on Heap only as it part of userdefined type clas i.e. reference type.
When you mark it as Ref that means you are passing it address not object and what every change made to it will change value stored on the given address.
If you have declared value type in the method then it will get stored on stack, and that adddress will be pass in ref.
So point is when you mark variable as Ref it doesnt allocate memory on heap , it will remain where it is (i.e. on heap/stack). Ref only tells that you are passing address so change made to variable will reflect to adress.
this might help : Reference type modification vs change of reference

C# define that a class instance can never be null (it only contains no data)

Out of curiosity: Is there a way to create a class whose reference to the class instance can never be set to null?
Like haveing only a readonly pointer that can only be set to null by the class itself.
What I have in mind:
I would want to have an easy to read /use object that either exists with data or exists without (shown by an attribute like hasData = false). It is always accessable and should never be null / point to nowhere which as a side effect gets also rid of NullReferenceExceptions for objects that are sometimes supposed to not have a value without the need of checking for null.
This feature does not exists (yet). There is big discussion of non-nullable reference types at Roslyn forum: non-nullable reference types (the one billion $ mistake). But currently you cannot restrict reference type variable from assigning null value.
You can use value type (struct) instead, but it's not stored in heap, passed by value etc.
All other options will not guarantee that someone will not assign null to variable of your reference type. But you still can use something like Null Object pattern to simplify your life (processing objects without data in same way as usual objects).
In such a case, you may want to use a struct instead of a class. Class is a reference type and therefore its default value is null, hence a variable containing an instance can be nulled (assigned null). There is no way to prevent it. On the other hand, struct is a value type and default for struct is an empty struct - i.e. a struct whose members are set to their defaults (0 for an int field, null for a field of a reference type etc.)
Example of a struct
public struct Foo
{
public int Bar;
}
And its usage (notice it is not instantiated but still it is NOT null)
Foo foo;
foo.Bar = 1;
More about structs can be found here on the MSDN sites.
As Anton mentioned, you could use a struct which cannot have a default value of null. But I am thinking you want something more like this:
public class DataObject
{
public static bool HasData
{
get
{
return myObject != null;
}
}
public static DataObject PresistentDataObject
{
get
{
return myObject;
}
}
static DataObject myObject = new DataObject();
}
This code seems like bad practice. And maybe you'd want to resort to something like dependency injection with a singleton which will avoid setting up a state class like this.
Typically, the motivation behind such a question drives the qualities/properties of a solution.
Here, I suppose, the motivation is to avoid runtime exceptions of (faulty) code which tries to access a null reference as if it held an instance.
class Foo<T> {
T data; // might be null or hold an instance...
Foo<T>() {
data = GetInstanceOfTInMysteriousWays(); // might return null...
}
bool DoSomething() {
return data.Value > 5; // might throw an exception...
}
// ... more members...
}
To prevent this type of errors, you could borrow from C#'s cousin language F#.
If the function T GetInstanceOfTInMysteriousWays<T>() by design and contract is permitted to either return an instance or a null value, a better design of that function would be to have it return not T but an Option<T>. Then, the type of Foo.data would not be T but Option<T> and the user code in DoSomething() could not simply access member data.Value. Thus, this common pattern of bugs would be eliminated.
// Improved code from above
class Foo<T> {
Option<T> data; // Option is a struct type and cannot be null...
Foo<T>() {
data = GetInstanceOfTInMysteriousWays();
}
bool DoSomething() {
if (data.IsSome() ) {
return data.TryGetValue().Value > 5;
}
return false;
}
}
Now the only question is, where to find that Option type in C#? There are several github projects creating such a type (google is your friend). You could also consider to link the F# core library and use the Option type defined there, maybe along with a little helper as is shown in this gist snippet.
If your class is named foo, then you would have at least one constructor (possibly more). In that constructor you would assign the variable to false.
public foo(){
hasData = false;
}
As #Anton points out, this only works if the variable is instansiated.
foo f = new foo();
it would still be null if you assigned it as null:
foo f = null;
I'm not sure, I understand the question correctly or not. Let me add
some points here:
Hope that you misunderstand the term Instance, If you create an instance of the class then it will not be null, Let myClass be a class that you have created already. You are not creating any instance of the class by using myClass myClassObject. The myClassObject will became an instance of the class only when an instance of the class is assigned to it, Until then it is null which means not existing.
As others have mentioned, you'd need a struct for that.
However, we can tackle this from a different angle (in a class):
Since the variable can point to null, let's define the variable in a way that it can't be set to null:
private Class1 _c = new Class1();
public Class1 c { get { return _c; } set { if (value != null) _c = value; } }
so c will not be set to null.
A struct per your requirements:
struct Struct1
{
public bool hasData { get { return Data != null; } }
public Class1 Data;
}

Why is the parameter is not updated?

I have a class that uses another class.
The first class have this method:
public void myMethod()
{
//Parameters are an enumeration.
// Really is a exchange variable between this class
//and the other class.
Paramters myParameter = Parameters.Option1;
MyClass2 myOtherClass = new MyClass2(myParameter);
}
The second class:
public enum Parameters { Option1, Option2, Option3 }
MyClass2
{
Parameters _myParameters;
Public MyClass2(Parameters paramParameters)
{
_myParameters = paramParameters;
}
private void clickButton()
{
_myParameters = Parameters.Option2;
this.Dispose();
}
}
What I what it is create a dialog and Parameters are an enumeration that is to serve as exchange between the main window and the dialog to notify about the selection in the dialog.
However, when in the clickButton I change the value of the _myParameters, it is not changed in the object that was passed as parameter in the constructor of MyClass2.
If instead of using an enumeration as exchange variable I create a class that has the enumeration, then I can get the selection. The exchange class would be like this:
class MyExchangeClass
{
Parameters myOption;
}
Then the code would be:
public void myMethod()
{
//Parameters are an enumeration.
// Really is a exchange variable between this class
//and the other class.
MyExchangeClass mySelection= new MyExchangeClass();
MyClass2 myOtherClass = new MyClass2(mySelection);
}
The second class:
public MyExchangeClass
{
Parameters enum MySelection { Option1, Option2, Option3 }
}
class MyClass2
{
MyExchangeClass _mySelection;
Public MyClass2(MyExchangeClassparamParameters)
{
_mySelection= paramParameters;
}
private void clickButton()
{
_mySelection.MySelection = Parameters.Option2;
this.Dispose();
}
}
In this way, the Class1, the main window, gets the updated value in the property of the class MyExchangeClass.
I would like to know why in the first solution the enumeration is not updated, because if it would possible, I would like to avoid the needed to wrap the enumeration in a class.
However, when in the clickButton I change the value of the _myParameters, is not changed in the object that was passed as parameter in the constructor of MyClass2.
No, it wouldn't be. The value was passed in by value - the two variables (myParameter and _myParameters) are independent variables. A change to one variable does not affect the other variable. This is how all types work in C#.
For changes to a parameter within a method to be seen by the caller, you could use a ref parameter, but that's not viable in your case as you're changing an instance variable which was originally populated via a parameter.
You could wrap the value in a mutable class, pass a reference to an instance of that class into MyClass2, and then mutate the object within MyClass2 - that change would be seen within your first class, because that would be changing the data within the object rather than the instance variable of MyClass2. It's hard to know whether or not that's actually a good solution though, as we have so little context - with names like MyClass and myMethod we have no clue as to the bigger picture of what this is trying to achieve.
In your first solution the value of the enumeration inside the class didn't change because enumeration is a value type, and this line:
_myParameters = paramParameters;
made a copy of paramParameters and _myParameters is a completely separate, standalone object.
In your second example, MyExchangeClass is a reference type, so this line:
_mySelection= paramParameters;
made _mySelection point to exactly the same object as paramParameters reference was referring to.
From the documentation:
Variables that are based on value types directly contain values. Assigning one value type variable to another copies the contained value. This differs from the assignment of reference type variables, which copies a reference to the object but not the object itself.
And an enumeration is a value type, ibidem:
The value types consist of two main categories:
Structs
Enumerations

passing objects as parameters

The application is printing 24 but shouldn't it be printing 18 when we know that without ref keyword only a copy of object is passed and no change is made to the original object.
I have created a class called myclass and an object me. age is a public variable in class myclass.
I have set me.age as 18 and through the method show I have changed it to 24.
class Program
{
static void Main(string[] args)
{
myclass me = new myclass();
me.age = 18;
show(me);
Console.WriteLine(me.age);
Console.ReadLine();
}
public static void show( myclass you)
{
you.age = 24;
}
}
class myclass
{
public int age;
}
Don't confuse the variable and what the variable points to.
When you have:
MyClass myVar = new MyClass();
MyClass myVar2 = myVar;
That will create only a single instance of an object, but 2 variables pointing to it.
The same thing is happening to your parameter: you is a copy of the variable me, but both point to the same object. So when you modify you.age, you are also modifying me.age.
In your function, if you then did
you = new myClass();
only then would me and you refer to different objects. If you did this, me would still point to the original object.
If you added ref to the parameter you, then if you did
you = new myClass();
then the variable me would be updated to point to that same object.
For objects, you need to separate the variable from what the variable points to.
It's printing the right thing.
myclass is an object, and the default behavior is to pass the reference of the object in C#, so when you don't specify anything, you pass the reference.
If you declare struct myclass though, you'll have the behavior you want, because structs aren't references by default.
You're probably confusing this with C++ classes. In C#, classes are reference types, which means that whenever you have a variable of a type that's class, that variable doesn't hold the object itself, it holds only a reference to it (you can think of it as a pointer). So, when you pass your object into a method, you actually pass a reference to that object. This means the behavior you're observing is correct.
C# also supports value types (unlike e.g. Java), which you create by using struct instead of class. If you changed myclass into a srtuct, you would get the behavior you expected.
You are confusing value types and reference types.
public void addTwo(int a)
{
a += 2;
}
...
int a = 5;
addTwo(a);
Console.WriteLine(a); // will give "5";
public void addTwo(ref int a)
{
a += 2;
}
...
int a = 5;
addTwo(ref a);
Console.WriteLine(a); // will give "7";
For reference types (anything that is defined as class instead of struct, what you are passing on is a reference to the object, not a copy. So you are in fact changing the object.
You are sending an object to your function.
Not an atomic type or a struct, therefor it is sent by reference (this is how C# works), anything you change in this object in the function will also change in the original object because it is the same.
More information about passing parameters: http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx

How to use ref in C#

I've created a class that takes in an object as a parameter by ref. When it takes this object in it's construct it is null. Why does it stay null (uninitialized)?
// example code, not real
class Test{
object parent;
public Test (ref object _parent)
{
parent = _parent;
}
}
object n = null;
Test t = new Test (ref n);
n = new Something ();
When I tried it with a different class (http://pastebin.com/PpbKEufr), it stayed null
Yes, parent will stay null regardless of what you eventually assign to the variable n. The ref keyword will pass the actual reference to n (as opposed to a copy of it) into your method, and is typically used if your method was intended to assign a new object instance to the parameter.
Inside your method, you are making a copy of the reference that n points to, in this case null. When the method completes both n and parent point to null. When later you assign to n, you haven't changed the object to which n and parent point, rather you have asked n to point to a new location, leaving parent still pointing to null.
If you were to create an instance of an object and assign it to n, then parent would point to the same object and any changes to that object's properties would be visible to your class. The same would be true if you did not pass the parameter as ref, as the reference copy also would point to the same object instance.
Hope that helps.
It is not possible to change a private member of a class that way as this would break the idea of encapsulation.
In order to change (i.e. replace) an object stored in a private field you must do so explicitly via a public property or method of that class, e.g.
class Test
{
object parent;
public Test (ref object _parent)
{
parent = _parent;
}
public object Parent
{
get { return parent; }
set { parent = value; }
}
}
object n = null;
Test t = new Test (ref n);
n = new Something ();
t.Parent = n;
This way the language makes sure that data of an object cannot (accidentally) be changed from the outside, which might lead to the strangest effects.
The ref arguments in C# refer to the instance "pointed" by the argument.
For example, if you'd change _parent in the constructor and store it in other instance, then n would change too.
In the posted code you're copying the referenced instance (null) into parent. Meaning, it copies the referenced instance into the field and not the reference of the argument itself.
For example, method that changes the ref argument:
public void M(ref object arg)
{
arg = new object();
}
And a usage example:
[Test]
public void SetReferenceArgument()
{
var myClass = new MyClass();
object arg = null;
myClass.M(ref arg);
Assert.That(arg, Is.Not.Null);
}
ref argument lets us assign an instance into the argument which will change the reference both in the of the method and in the context of the caller.

Categories

Resources