I know when an assignment statement is made a new object is not made, a reference to the object is made instead. For instance I want to do the following:
word.start = newWordPos.First.Value;
word.end = newWordPos.Last.Value;
But every time the values of newWordPos.First.Value or newWordPos.Last.Value is updated, then word.start and word.end are updated as well. Is there any way I can get them to be assigned the actual value so that this does not occur?
Since your type is a class, you need to clone the object, not just assign a reference.
The type itself needs to provide some mechanism of creating a deep copy. The framework provides an interface (IClonable) which is for allowing a single Clone method - though it's not clear what form of cloning is being done (ie: full deep clone, etc).
Related
With a dictionary with a nested class, for example: Dictionary<int, BankAccount>,
what's the difference between creating the class first as an object, then linking it to a new Dictionary, and creating the object directly into the Dictionary itself, for example:
dict.Add(1, new BankAccount());
var acc = new BankAccount();
dict.Add(1, acc);
Is there any benefit of using one over another?
The advantage of creating the object first, and adding it by reference is, that you hold the reference in the current method, and thus have full access to it.
If you create the object in line with the add method, you would have to fetch the object from the dictionary to gain access.
I do not see any other differences.
Creating the object first, could have code-maintainability benefits, when you find out later that the object needs to be modified.
The only real difference I could imagine is if you use the first option, the garbage collector doesn't have to hold onto a variable reference and can release the memory sooner. Other than that, it is more concise to choose the first option. Functionally, your options accomplish the same task.
My question concerns the use of objects in C#. I think I understand what's happening, but I want to understand why. For reasons I won't go into, I want to create a temporary copy of an object with its current data (current state). So I thought I could create a new object, assign it the original object, then change the original object. At that point I would have two objects in different states. But what happens is that the copied object ends up looking exactly like the first. Here is some code to illustrate:
Order o1 = new Order();
o1.property1 = "test 1";
Order o2 = new Order();
o2 = o1;
o1.property1 = "test 2";
But at the end of this code, both o1 and o2 have property1 set to "test 2". I think I realize that all objects are just pointers, so if you change one it changes another, but I can't understand why this is, or why it is useful. Is there some fundamental thing I'm missing here? Also, what would be the best way to accomplish what I want to do? Which is: store the state of the object, make changes, then revert if necessary. Hopefully this makes sense.
An object variable in C# is a reference (not a pointer) to a specific object in memory. When you declare
Order o2 = new Order();
you are creating a new Order object in the heap, and allocating a reference to that object to your o2 variable. When you then state
o2 = o1;
you are telling the compiler to make o2 a reference to o1. At this point, the reference to the original o2 object is lost, and the memory for that object will be removed during the next garbage collection sweep.
Henceforth, both o1 and o2 both reference the same object in memory. To copy information from one object to another, you will need to implement a procedure to instantiate a new destination object and copy all of the data from one object to the other. See the MSDN docs on ICloneable for more info.
What you are referring to is the difference between value types and reference types. Apparently your Order object is a reference type, I would assume it is a class.
Classes are reference types meaning they are "pointers". One of the reasons for this is performance as you do not want to copy huge amounts of data every time you assign a variable.
Structures are value types and would be copied in memory when you assign them.
You have 2 solutions :
Use a struct instead of class
Clone your object using either MemberwiseClone if it is very simple, or use your own method if you need to perform a deep clone.
This is by Design. If you want to clone and keep the clone independent i would recommend to Implement a "cloning" mechanism on your types. This can be ICloneable or even just a constructor that takes an instance and copies values from it.
Regarding your question
what would be the best way to accomplish what I want to do? Which is:
store the state of the object, make changes, then revert if necessary
A simple method is to simply serialize the object, e.g. using XMLSerializer. Then if you want to throw away your changes, just deserialize the original object and replace the modified object with the original version.
Use Structures to accomplish your task, Classes are reference type and Structs are Value type.
Classes are stored on memory heap
Structs are stored on stack.
for more info search Structs vs Classes and learn differences
Objects are, by definition, a 'pointer'; they hold a reference to your data, and not the actual data itself. You can assign it a value type though and it will give the appearance of holding the data.
As was mentioned above, understanding Value types vs. Reference types is key.
Java has no concept of any non-primitive data type other than an object reference; since almost anything one can do with an object reference involves acting upon the object referred to thereby, the . operator in Java . Although .net does have non-primitive value types, most .net languages maintain the convention (different from C and C++, which use -> to access a member of a pointed-to object and . to access a member of a structure) that the same . operator is used for both "dereference and access member" and "access value-type member".
Personally, I dislike Java's "everything is an object reference" design, and .net's decision to have value types and reference types use the same . operator to mean very different things doesn't help, but it is what it is.
I am currently struggling to understand something i just saw somewhere.
Lets say I have two classes :
class MyFirstCLass{
public int membVar1;
private int membVar2;
public string membVar3;
private string membVar4;
public MyFirstClass(){
}
}
and :
class MySecondClass{
private MyFirstClass firstClassObject = new MyFirstClass();
public MyFirstClass FirstClassObject{
get{
return firstClassObject;
}
}
}
If i do something like this :
var secondClassObject = new MySecondClass(){
FirstClassObject = {membVar1 = 42, membVar3 = "foo"}
};
secondClass is an instanciation of MySecondClass, and does have one private member variable of type MyFirstClass wich has a readOnly property. However, i am able to change the state of membVar1 and membVar2. Isn't there any encapsulation problem ?
Best regards,
Al_th
The fact that the FirstClassObject property on MySecondClass has no setter does not mean that the object returned from the getter becomes immutable. Since it has public fields, these fields are mutable. Therefore it is perfectly legal to say secondClassObject.FirstClassObject.membVar1 = 42. The absence of the setter only means that you cannot replace the object reference stored in the firstClassObject field with a reference to a different object.
Please note: You are not changing the value of MySecondClass.FirstClassObject. You are simply changing the values inside that property.
Compare the following two snippets. The first is legal, the second is not as it tries to assign a new value to the FirstClassObject property:
// legal:
var secondClassObject = new MySecondClass(){
FirstClassObject = {membVar1 = 42, membVar3 = "foo"} }
// won't compile:
// Property or indexer 'FirstClassObject' cannot be assigned to -- it is read only
var secondClassObject = new MySecondClass(){
FirstClassObject = new MyFirstClass {membVar1 = 42, membVar3 = "foo"} }
Basically, your code is just a very fancy way of writing this:
var secondClassObject = new MySecondClass();
secondClassObject.FirstClassObject.membVar1 = 42;
secondClassObject.FirstClassObject.membVar3 = "foo";
And that's how I would write it. It is explicit and understandable.
Neither a storage location of type MyFirstCLass, nor the value returned by a a property of type MyFirstCLass, contains fields membVar1, membVar2, etc. The storage location or property instead contains information sufficient to either identify an instance of MyFirstCLass or indicate that it is "null". In some languages or frameworks, there exist reference types which identify an object but only allow certain operations to be performed on it, but Java and .NET both use Promiscuous Object References: if an object allows outside code that holds a reference to do something with it, any outside code that gets a reference will be able to do that.
If a class is using a mutable object to encapsulate its own state, and wishes to allow the outside world to see that state but not allow the outside world to tamper with it, it must not return the object directly to the outside code but instead give the outside code something else. Possibilities include:
Expose all the aspects of state encompassed by the object individually (e.g. have a membVar1 property which returns the value of the encapsulated object's membVar1). This can avoid confusion, but provides a caller with no way to handle the properties as a group.
Return a new instance of a read-only wrapper which holds a reference to the private object, and has members that forward read requests (but not write requests) to those members. The returned object will serve as a read-only "view", but outside code will have no nice way to identify whether two such objects are views of the same underlying object.
Have a field of a read-only-wrapper type which is initialized in the constructor, and have a property return that. If each object will only have one read-only wrapper associated with it, two wrapper references will view the same wrapped object only if they identify the same wrapper.
Create an immutable copy of the underlying data, perhaps by creating a new mutable copy and returning a new read-only wrapper to it. This will give the caller a "snapshot" of the data, rather than a live "view".
Create a new mutable copy of the underlying data, and return that. This has the disadvantage that a caller who tries to change the underlying data by changing the copy will be allowed to change the copy without any warnings, but the operation won't work. All of the arguments for why mutable structs are "evil" apply doubly here: code which receives an exposed-field structure should expect that changes to the received structure won't affect the source from which it came, but code which receives a mutable class object has no way of knowing that. Properties should not behave this way; such behavior is generally only appropriate for methods which make clear their intention (e.g. FirstClassObjectAsNewMyFirstClass();
Require that the caller pass in a mutable object of a type that can accept the underlying data, and copy the data into that. This gives the caller the data in a mutable form (which in some cases may be easier to work with) but at the same time avoids any confusion about who "owns" the object. As an added bonus, if the caller will be making many queries, the caller may reuse the same mutable object for all of them, thus avoiding unnecessary object allocations.
Encapsulate the data within a structure, and have a property return the structure. Some people may balk at such usage, but it's a useful convention in cases where a caller may want to piecewise-modify the data. This approach only really works if the data in question is limited to a fixed set of discrete values (such as the coordinates and dimensions of a rectangle), but has the advantage that if the caller understands what a .NET structure is (as all .NET programmers should) the semantics are inherently obvious.
Of these choices, only the last two make clear via the type system what semantics the caller should expect. Accepting a mutable object from the caller offers clear semantics, but makes usage awkward. Returning an exposed-field structure offers clear semantics but only if the data consists of a fixed set of discrete values. Returning a mutable copy of the data is sometimes useful, but is only appropriate if the method name makes clear what it is doing. The other choices generally leave ambiguous the question of whether the data represents a snapshot or a live "view".
yesterday I spent some time trying to find a bug. Long story short, finally I realized that it was because of this constructor:
public Triangle(List<Vertex> vertices) {
this._values = vertices;
}
I tried to initialize an object with a list of values and the object just took a reference to my object instead of getting the values from list. If I don't abandon the list that I passed as a parameter and use it later for something else like initializing something else with the same values or if I decide to clear it and fill with new values, I obviously destroy the state of my Triangle object without knowing it.
My first reaction was to "fix the bug" in the constructor but then I started thinking if it's really the way it should be. What's the good practice that covers things like that? In general, what should I think about constructors/init methods that take a list of values? Should they leave it intact? Am I allowed to reuse the list and whose fault is it when it leads to an error?
I mean, I obviously can do something like that:
var triangle = new Triangle(new List<Vertex>(vertices));
but shouldn't it be done by the creators of the Triangle class already?
I would like to know some guidelines on that. Thanks.
Yes, the receiving class (Triangle) should make a copy, unless the design is to intentionally share the List.
Sharing can be useful but is the exception. I don't think a Triangle wants to share its List of vertices with something else.
Note that it could still be sharing the vertices (elements).
Personally I agree with Henk; you should create a copy.
/// <summary>
/// Initialises a new instance of the <see cref="Triangle"/> class that
/// contains elements copied from the specified collection.
/// </summary>
/// <param name="vertices">
/// The collection of vertices whose elements are to be copied.
/// </param>
public Triangle(IEnumerable<Vertex> vertices)
{
this.Vertices = new List<Vertex>(vertices);
}
Whatever you choose just make sure you document it so consumers know what behaviour to expect.
Therefore consumers know that they can safely call new Triangle(vertices).
C# is a pass-by-value language, but since a list is a reference type, it passes its reference by value. As you stated, this means you are passing a shared reference of the list to the constructor of your class. Modifications made anywhere in the code will affect the same list.
It depends on the desired behavior of your class as to what is the appropriate action. If you want to make a deep copy, the easiest way is to just allocate a new list in the constructor and pass in the IEnumerable reference to the list's constructor.
If you want to share the reference, it is a completely valid solution, just make sure you document your class (or name your class) appropriately.
Passing a List object to the constructor would be considered poor design in this case. Perhaps a better solution would be to use a method
class Triangle
{
List<Vertex> Vertices = new List<Vertex>(); // The triangle owns the vertex collection...
public void SetVertices(IEnumerable<Vertex> vertices)
{
this.Vertices.Clear();
this.Vertices.AddRange(vertices);
}
}
I'd say that this is a documentation issue. The documentation, even if it's just the intellisense docs, should say whether the class is initialized using the values from the given list, or if it will use the given list directly. Given any mutable reference type, this is a valid question and should be documented.
Lacking proper documentation, I'd say it's up to you, the consumer of the class, to protect yourself against undocumented behaviors. You have two choices:
Find out for yourself what documentation should have told you. You can use either Reflector or simple experimentation to determine what the code does with the mutable object you pass it.
Protect yourself against the class's behavior, whatever it may be. If a class takes a mutable object, don't reuse that object. This way, even if the class's behavior changes later, you're secure.
In your specific case, I don't think that the Triangle class is wrong. It's constructor could have taken an IEnumerable<Vertex>1 and initialized a member List<Vertex> with those values, but instead, it's designer chose to take a List<Vertex> directly and use that. That could have been a performance-based decision.
1 To be complete, if a bit pedantic, I should mention that even if it took an IEnumerable<Vertex>, you could still run into this same issue. The class could still store and reuse a reference to this object, and therefore be sensitive to changes later made to the list. In this case, however, I would consider the Triangle class to be broken. Convention states, with few exceptions, that a method or constructor that takes an IEnumerable will use it once and then discard it.
What you need is a Clone or deep copy of the List.
Refer this answer for cloning a list
And this for more about deep copies, in general
If copying an object just create a new reference to the same object in memory then i don't understand why it is useful, because it only creates another name for the same object.
Copy, means for me, creating a clone of the object in another memory location.
Then i could manipulate 2 separate objects which are the same only at the moment of their copy but whom their live will be different.
I use C#.
Can someone explain me...
Thanks
John
Copying usually means actually creating a new object. However, the new object may be a shallow copy, so it may not actually hold references to new copy of the fields.
It's possible that the class you are looking at is Immutable, and the class designer decided that there was no need for the memory overhead.
Copying by reference is useful behaviour when you want to "pass around" an object to many components, either to allow many components to modify the state of the single object or to allow the functionality of the object to be used by multiple components.
Additionally, passing by reference avoids copying values, which can often produce a smaller memory footprint for an application.
If you wish, you can implement a Clone method on an object which will perform the behaviour you're asking for, allowing you to have a separate object to work with.
Lastly, if the behaviour of passing by reference doesn't seem natural for your object (for example your object is a fundamental value such as coordinate data), you can create a struct instead of a class. A struct or "structure" is copied by value, so when you pass it to a method, the entire object is copied and the copy passed to the method.
there are 3 kinds of copy
reference copy :giving another name to the object
shallow Copy : will create another copy of the object skeleton without the inner data
deep copy : will create another copy of the object and the data
you can read more about object copy in this link
http://en.wikipedia.org/wiki/Object_copy
You are right in your understanding that there are two, (actually three if you consider deep vs shallow copies) ways to reproduce a reference object.
You can copy the variables address into another variable (Same object on the Heap, now with another reference to it), or
You can create a new object on the heap and copy the values of the original objects properties and fields into the new object. This is generally called a Clone, and can be done in two ways Shallow or Deep.
Shallow Copy. Here you only copy primitives, and, where the object has properties which reference other reference types, only copy the reference, (i.e., the address), this is called a shallow copy, or,
Deep Copy. Here you copy primitives, and you can create new objects for each property which references another reference type.
You are right that copying creates a new object. I think the misconception comes from thinking of objects like primitives. Copying a primitive value and copying an object is done in different ways.
int x = 5;
int y = x;
y is a copy of x.
Object a = new object();
Object b = a;
b is a reference to a rather than a copy of a. To copy a you do need to write specific code to clone the object yourself.
I believe someone else will complain if Microsoft chooses implementing it in your way. It depends on the context that you using it to say which way is better. It's wise to take more efficient way as the default implementation.
Also, reference type is kind of like a pointer, so it makes sense to just copy the "pointer" itself in this case.
If you find this behavior is not what you desired, you can use your own implementation as well.