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.
Related
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 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).
I have in my program a struct type called Square which is used to represent the location (int Rank, int File) of a square on a chess board.
If I assign Square by new Square sq(); say and then I want to reassign it, is it better to do so by
sq = new Square(rank, file);
or by writing an internal Set method and calling Set thus
sq.Set(rank, file);
What I am asking is when you use new on a struct, does the runtime reallocate new memory and call the constructor or does it reuse the existing memory? If it does the former then it would be better to write a Set method to avoid overheads would it not? Cheers.
The traditional thinking these days is the value types should be immutable, so you would not want to have a Set method unless that is returning a new Square object and not mutating the original. As such,
sq = new Square(rank, file);
And
sq = sq.GenerateSquare(rank, file); // renamed Set method from original question to appease comments
Should ultimately perform the same operation.
But given this approach, GenerateSquare would also possibly be better as a static method of Square rather than something depending upon any given instance. (An instance method would be more useful if something about the existing instance was used in the creation of a new instance.)
Structures are value types, so a simple assignment will do the job:
Square sq = new Square(rank, file);
Square anotherSq = sq;
Worrying about the weight of garbage collection or memory use is something you should not be concerned with until you have profiled your application and know it will be an issue. A simple structure like this is not going be taking up much space and likely not the cause of problems if your program does hit a bottleneck.
For structs... space for new structs is created on the stack, (see NOTE), not the heap, and is not subject to garbage collection. If the assignment variable is an already existing copy of the struct, then it is overwritten. No additional memory is used.
NOTE: If you create a new struct and assign it to a variable that is a property of a reference type, then yes, the reference type is on the heap, but the memory slot the struct is copied to is the already existing memory slot for that already existing reference type, no new heap memory is allocated. And the struct is not independantly subject to garbage collection....
But others' comments about your design are correct, structs should generally only be used for immutable domain objects, things that are simple and easy to create (small footprint) and have no identity (i.e., one telephone number object set to (802) 123-4567 is equivilent to and can be used anywhere else you need a telephone number object set to (802) 123-4567
So in general, these objects should not have constrcutors or property setters, they should have static factory methods that create instances of them.
We have a class variable ArrayList binaryScanData in a class. In all methods having access to it, we put lock(binaryScanData) on it because it is shared. Now we want to move one of those methods out to another util class to make it a static method. We will pass that binaryScanData into the method like this:
public static void convertAndSaveRawData(ref MemoryStream output, ref ArrayList binaryScanData)
Our questions are followed:
how can we sychoronize that binaryScanData? can we do the same as it is originally?
ref is necessary? It will only be read in that convertAndSaveRawData method.
The ref isn't necessary, it is only needed if you are going to change the reference itself (ie, assign a new list to it). You can still lock on the object if you like. I recommend locking on SyncRoot, which I'm not sure if ArrayList has. If not, you might consider moving up to List<T>.
You don't need to make it a ref parameter unless you write binaryScanData = something.
You can lock on the parameter the same way you lock on anything else.
The C# lock keyowrd locks on an object instance; it doesn't matter what the instance came from.
This sounds very wrong. I can imagine that your class objects share a single ArrayList instance and that therefore code that accesses it needs to be synchronized. But that would make the ArrayList object reference static as well, why do you have to pass it as an argument?
If other code needs to call this static method without having to use a reference to your class object then they'd probably have to pass their own instance of the ArrayList. Then it doesn't make sense anymore that you would need to lock. The calling code needs to take care of locking. Only it knows in what other places that particular ArrayList object gets used.
Sorry, I can't make much sense of it. That starts by you using the ArrayList object as the lock argument. You can't lock data, you can only lock code that uses data.
how can we sychoronize that binaryScanData? can we do the same as it is originally?
By locking the same object instance from every piece of code that requires synchronization.
Note that this does not necessarily imply locking the same object you're modifying. In fact, that's dangerous and considered bad practice. It leaves you susceptible to deadlocks and other nastiness because some other code could lock the same object. You're best off creating your own, private object and using that for synchronization.
ref is necessary? It will only be read in that convertAndSaveRawData method.
No, it's not. You've got two entirely different concepts mixed up.
You can create a synchronized wrapper to an existing ArrayList that internally locks on all get/sets:
ArrayList unsyncList = new ArrayList();
ArrayList syncWrapperList = ArrayList.Synchronized(unsyncList);
There is a perf cost to the locking, so only use the wrapper where you must synchronize every call.
ref isn't needed for either parameter as both will be passed by reference anyway, as they are reference types.
As has been pointed out, ArrayList is not recommended as a way of holding a list of items anymore, as it often requires boxing and is therefore usually a lot slower. Try List<T> instead unless you are using 1.1
Those two points don't answer you're main question though: to synchronise a list is not a trivial task, as the .NET implementation is not thread safe. You can see a whole discussion on it: Why is C# List<> not thread-safe? You can synchronise the list inside your own class, but it could still be altered outside of that class.
One technique, if you have created the list yourself, is to make it a read-only list, and provide methods to add to it by subclassing List<T> or IList<T>.
This ThreadSafe List article attempts to make a generic thread-safe list, but if you read the comments at the bottom of the page it still has shortcomings.
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.