Supose that I have this:
CustomObject myCO1 = new CustomObject();
CustomObject myCO2 = myCO1;
CustomObject myCO3 = new CustomObject();
myCO1 = myCO3;
I would like that myCO2 has the same reference than myCO1, to myCO3. Is there any way to do that?
Thank so much.
No, assigning a new reference just copies the reference value into the new variable. When you change it's reference the other variables that references the same place are not affected.
So in your case, myCO2 references the old location of myCO1. And myCO1 and myCO3 are referencing to same location.
It sounds a little bit like you could use a primer on references and values in C#. Specifically: "If x is a variable and its type is a reference type, then changing the value of x is not the same as changing the data in the object which the value of x refers to"
However, let me edit your example for a bit of clarity:-
CustomObject myCO1 = new CustomObject("A");
CustomObject myCO2 = myCO1;
CustomObject myCO3 = new CustomObject("B");
myCO1 = myCO3;
You can see clearly that myCO2 refers to "A", even after you change myCO1 to refer to "B". This is because while a reference refers to another object, it is itself a value.
There are largely two ways you can achieve the outcome you desire.
The first option is using a reference type (rather than a value) to refer to your CustomObject:-
public sealed class Reference<T>
{
public T Value { get; set; }
}
...
Reference<CustomObject> myCO1 = new Reference<CustomObject>()
{
Value = new CustomObject("A");
};
Reference<CustomObject> myCO2 = myCO1;
CustomObject myCO3 = new CustomObject("B");
myCO1.Value = myCO3;
The second option you have is to encapsulate the logic you require in a method and use the ref keyword
Related
Is there a way for me to read a property value I defined already in an anonymous object while creating the object?
here is an example
var a = new { PropA = "something", PropB = this.PropA + " and another thing"}
Perhaps defining it in a variable right before the declaration of a would work?
var somethingValue = "something";
var a = new { PropA = somethingValue , PropB = somethingValue + " and another thing"}
Otherwise, I don't think you would be able to. You have yet to instantiate the object so this.PropA wouldn't work. To further elaborate, your question was "Is there a way for me to read a property value I defined already in an anonymous object while creating the object?" which doesn't entirely make sense, because you are creating the anonymous object, so the value isn't already defined in the object.
Using dynamic binding can be helpful:
dynamic myObject = a;
myObject.PropB = ... //you can access any property that you know it exists
In PHP we can remove one property and its value from the object simply with this code:
$foo->bar = "Something";
unset($foo->bar);
I want to do this in C#.
Imagine that the object is:
var a = new {foo = bar, one = "one"}
How I can remove foo from the object?
Types are defined at compile-time, so there's no removing of properties, not in c#. An anonymous type is a type just like classes that you create; it's just that the name is hidden from you.
The closest you can get to your answer is to define a new type that omits the property you wish to remove:
var b = new { one = a.one };
I have a class with one property
public class Test
{
public string Name { get; set; }
}
private void TestReference()
{
Test tst1 = new Test();
tst1.Name = "ASP.NET";
Test tst2 = tst1;
tst1.Name = "JAVA";
string name = tst2.Name; // Shows "JAVA" because of reference sharing
tst1 = null;
bool isNullObj = tst2 == null; // isNullObj is false
}
In above example when I set tst.Name = "JAVA" this change also reflect in tst2.Name because of reference sharing, this I understand but when I set tst = null; tst2is still alive.
my question is, if it is sharing reference! why tst2 is still alive?
tst1 and tst2 are variables which hold reference to objects in memory. If both point to same object, then you can change object via any of references.
If you resign a reference to one of variables, the other variable will still hold its reference. That's why setting tst1 to null (or to any other value) does not affect tst2.
Here is what you have in memory:
This (oddly enough) makes more sense when you think of references as pointers.
When I write:
tst1.Name = "JAVA";
I am going through the pointer and modifying the object itself. However, when I write:
tst1 = null;
I am just setting the variable (of pointer type) to null. The object it was pointing to is not affected. Thus,
tst2 == null
Will always return false.
Consider this case, without Reference Types:
int a = 1; // a = 1
int b = a; // a = 1, b = 1
a = 2; // a = 2, b = 1
// a == b -> false
This is the same thing that is happening with the presented code in the question. For reference types, only a reference value (or the "reference to an object") is stored in the variable. However, the variables themselves are separate and reassignment to one does not affect any other variable.
(The "sharing" behavior is explained because multiple variables, as in the question, can contain the same reference value and thus refer to the same object.)
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];
}
}
}
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.
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.
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
I have the following classes:
public class DrawableComplexEntity2D
{
public List<GameComponent> Components { get; set; }
// anothers properties, constructor, methods...
}
public class BoardCell : DrawableComplexEntity2D
{
public GoalPersonGroup GoalPersonGroup { get; set; }
public void CreateGoalPersonGroup(Goal groupType)
{
this.GoalPersonGroup = new GoalPersonGroup(groupType)
base.Components.Add(this.GoalPersonGroup);
}
}
So, when i do:
BoardCell cell1 = new BoardCell();
cell1.CreateGoalPersonGroup(Goal.Type1);
BoardCell cell2 = new BoardCell();
cell2.CreateGoalPersonGroup(Goal.Type2);
cell1.GoalPersonGroup = cell2.GoalPersonGroup;
When i update the cell1.GoalPersonGroup with cell2.GoalPersonGroup, the cell1.GoalPersonGroup is updated, but the cell1.GoalPersonGroup that is inside of the base.Components of cell1 doesn`t change and still the value of cell1 instead cell2. Why?
Yes, you are getting confused with references. Assigning a reference variable assigns the thing that is referenced.
eg
string str1 = new String("Hello"); //str1 has a reference to "Hello"
string basestr = str1; //basestr has a reference to "Hello" (NOT str1)
string str2 = new String("Goodbye"); //str2 has a reference to "Goodbye"
str1 = str2; //str1 has a reference to "Goodbye" (basestr still = hello)
Lists, as with all other variables, contain values. With a reference type (which I'm assuming GoalPersonGroup is), the value is a reference. If I have the following:
object a = ...;
object b = ...;
a = b;
All I've done is take the value of b (which is a reference) and copied that value to a. In the case of a reference type, I can perform operations on that value (like calling a.SomeProperty = "foo";) and those same changes in state will be reflected anywhere in the program where that particular reference is stored in a variable. In other words, if I were to inspect the value of b.SomeProperty, it would be "foo".
However, changing the value in the variable does not affect other variables that point to that value (except in the case of a ref parameter).
You've added a value that points to a reference to your List. You've also assigned that same value to a property. These two distinct memory locations contain the same value, and thus point to the same actual object. But later you're just reassigning the value of the property, which means that it now has a different value than what's stored in the list.
You are only changing the reference in the property cell1.GoalPersonGroup, not the one you have added to base.Components. To fix this, you'll have to add code in the setter of GoalPersonGroup to do what you want.