When is a shallow copy desirable (instead of a deep copy)? - c#

Can someone give an example of a situation where a shallow copy is needed?
Note that in some situations, shallow copy and deep copy are the same. This can happen when the object has no ownership over any of its subvariables; that is, all subvariables are aggregated. I'd like to see examples where the an object is composed from variables which it owns, and it still is desirable to copy them shallowly.
Remark: I don't care in which language the examples are given. I'm asking this question from a C++/Java/C# point of view, although I think copying is a language agnostic concept.

When the owned variables are immutable types, a shallow copy is sufficient. A deep copy is possible, but would only result in additional memory use.

One possible use case is when the composed objects can be derived from state information that is present in the shallow copy and you want, for instance, to serialize your object.
You can store the shallow copy and then rebuild the complete object from the state upon deserialization.

Coming from C++ POV, there would be one scenario that i will use shallow copy : when implementing copy-on-write mechanism.

class Element{
}
class Example {
private List<Element> elementList = new ArrayList<Element();
public List<Element> getElementList() {
return new ArrayList<Element>(this.elementList);
}
public void addElement(Element e) {
elementList.add(e);
}
public void removeElement(Element e) {
elementList.remove(e);
}
}
You want all modifications of Example.elementList to be done by object methods, but you want to expose elements stored in list. So you create getter which returns a shallow copy. Copy, because you don't want caller to modify object's list and shallow because you want to expose objects from list, not their copies.

If you look at the Gang of Four design patterns, there's a pattern called FlyWeight. Here's a quote from wikipedia:
A flyweight is an object that
minimizes memory use by sharing as
much data as possible with other
similar objects; it is a way to use
objects in large numbers when a simple
repeated representation would use an
unacceptable amount of memory.
This would be an acceptable use of a shallow copy.

As I pointed out in my answer to your related question, many languages don't really have the concept of shallow and deep copy. However, this class in C++, which prevents you from using a NULL pointer may be an example where a "shallow" copy is needed:
template <typename T>
struct NotNull {
T * p;
NotNull( T * t ) : p( t ) {}
T & operator *() {
if ( ! p ) {
throw "null!";
}
return * p;
}
};
The class does not own the thing pointed to, so no copy should be made.

My take on this is that the situations where you would use deep copy are different for C++ versus Java.
In C++, you might use deep copying to avoid difficult memory management issues, or to make it easier to implement a multi-threaded application.
In Java, deep copying is not necessary for those reasons. Since the languages are both garbage collected, it is not necessary to go through hoops to free data structures. So a deep copy is not necessary to simplify the problem. Similarly Java has built-in support for synchronizing access by multiple threads to shared data structures.
In most cases, deep copying is unnecessary in Java assuming that your application's data structures are well designed.

Shallow copies are quicker to make, which is often desirable for obvious reasons. The ultimate in shallow copying is obviously just a copy of a reference to the original object. If you're not mutating an object and can guarantee it won't get changed in other ways while you work with it then the more shallow the copy is, the better.

Remark: I don't care in which language the examples are given. I'm asking this question from a C++/Java/C# point of view, although I think copying is a language agnostic concept.
I think it depends quite a bit on the language.
In C++, copying plays a very different role than it does in Java/C#. In C++, I can't think of many cases where shallow copying makes sense. You'd usually just create references or pointers to an object instead. Copy constructors usually implement deep copies because in C++, an object takes ownership of its members, and is responsible for managing their lifetime. Because there's no GC, these ownership semantics become important, and you can't just have two objects pointing to a third without special care (do they use reference counting to keep the third alive? If not, which of the two objects owns it?)
I'd even say that the distinction between "deep" and "shallow" copies doesn't really make sense in C++. A copy creates all that is necessary for the newly created object to work. Sometimes, it shares a bit of data (typically data which isn't owned by either object), so it might not be a "true" deep copy", but it's not shallow either, because the bulk of the class typically is copied.

Related

Should I use Class or Struct in the following case (data structure with many fields)? [duplicate]

I'm about to create 100,000 objects in code. They are small ones, only with 2 or 3 properties. I'll put them in a generic list and when they are, I'll loop them and check value a and maybe update value b.
Is it faster/better to create these objects as class or as struct?
EDIT
a. The properties are value types (except the string i think?)
b. They might (we're not sure yet) have a validate method
EDIT 2
I was wondering: are objects on the heap and the stack processed equally by the garbage collector, or does that work different?
Is it faster to create these objects as class or as struct?
You are the only person who can determine the answer to that question. Try it both ways, measure a meaningful, user-focused, relevant performance metric, and then you'll know whether the change has a meaningful effect on real users in relevant scenarios.
Structs consume less heap memory (because they are smaller and more easily compacted, not because they are "on the stack"). But they take longer to copy than a reference copy. I don't know what your performance metrics are for memory usage or speed; there's a tradeoff here and you're the person who knows what it is.
Is it better to create these objects as class or as struct?
Maybe class, maybe struct. As a rule of thumb:
If the object is :
1. Small
2. Logically an immutable value
3. There's a lot of them
Then I'd consider making it a struct. Otherwise I'd stick with a reference type.
If you need to mutate some field of a struct it is usually better to build a constructor that returns an entire new struct with the field set correctly. That's perhaps slightly slower (measure it!) but logically much easier to reason about.
Are objects on the heap and the stack processed equally by the garbage collector?
No, they are not the same because objects on the stack are the roots of the collection. The garbage collector does not need to ever ask "is this thing on the stack alive?" because the answer to that question is always "Yes, it's on the stack". (Now, you can't rely on that to keep an object alive because the stack is an implementation detail. The jitter is allowed to introduce optimizations that, say, enregister what would normally be a stack value, and then it's never on the stack so the GC doesn't know that it is still alive. An enregistered object can have its descendents collected aggressively, as soon as the register holding onto it is not going to be read again.)
But the garbage collector does have to treat objects on the stack as alive, the same way that it treats any object known to be alive as alive. The object on the stack can refer to heap-allocated objects that need to be kept alive, so the GC has to treat stack objects like living heap-allocated objects for the purposes of determining the live set. But obviously they are not treated as "live objects" for the purposes of compacting the heap, because they're not on the heap in the first place.
Is that clear?
Sometimes with struct you don't need to call the new() constructor, and directly assign the fields making it much faster that usual.
Example:
Value[] list = new Value[N];
for (int i = 0; i < N; i++)
{
list[i].id = i;
list[i].isValid = true;
}
is about 2 to 3 times faster than
Value[] list = new Value[N];
for (int i = 0; i < N; i++)
{
list[i] = new Value(i, true);
}
where Value is a struct with two fields (id and isValid).
struct Value
{
int id;
bool isValid;
public Value(int i, bool isValid)
{
this.i = i;
this.isValid = isValid;
}
}
On the other hand is the items needs to be moved or selected value types all that copying is going to slow you down. To get the exact answer I suspect you have to profile your code and test it out.
Arrays of structs are represented on the heap in a contiguous block of memory, whereas an array of objects is represented as a contiguous block of references with the actual objects themselves elsewhere on the heap, thus requiring memory for both the objects and for their array references.
In this case, as you are placing them in a List<> (and a List<> is backed onto an array) it would be more efficient, memory-wise to use structs.
(Beware though, that large arrays will find their way on the Large Object Heap where, if their lifetime is long, may have an adverse affect on your process's memory management. Remember, also, that memory is not the only consideration.)
Structs may seem similar to classes, but there are important differences that you should be aware of. First of all, classes are reference types and structs are value types. By using structs, you can create objects that behave like the built-in types and enjoy their benefits as well.
When you call the New operator on a class, it will be allocated on the heap. However, when you instantiate a struct, it gets created on the stack. This will yield performance gains. Also, you will not be dealing with references to an instance of a struct as you would with classes. You will be working directly with the struct instance. Because of this, when passing a struct to a method, it's passed by value instead of as a reference.
More here:
http://msdn.microsoft.com/en-us/library/aa288471(VS.71).aspx
If they have value semantics, then you should probably use a struct. If they have reference semantics, then you should probably use a class. There are exceptions, which mostly lean towards creating a class even when there are value semantics, but start from there.
As for your second edit, the GC only deals with the heap, but there is a lot more heap space than stack space, so putting things on the stack isn't always a win. Besides which, a list of struct-types and a list of class-types will be on the heap either way, so this is irrelevant in this case.
Edit:
I'm beginning to consider the term evil to be harmful. After all, making a class mutable is a bad idea if it's not actively needed, and I would not rule out ever using a mutable struct. It is a poor idea so often as to almost always be a bad idea though, but mostly it just doesn't coincide with value semantics so it just doesn't make sense to use a struct in the given case.
There can be reasonable exceptions with private nested structs, where all uses of that struct are hence restricted to a very limited scope. This doesn't apply here though.
Really, I think "it mutates so it's a bad stuct" is not much better than going on about the heap and the stack (which at least does have some performance impact, even if a frequently misrepresented one). "It mutates, so it quite likely doesn't make sense to consider it as having value semantics, so it's a bad struct" is only slightly different, but importantly so I think.
The best solution is to measure, measure again, then measure some more. There may be details of what you're doing that may make a simplified, easy answer like "use structs" or "use classes" difficult.
A struct is, at its heart, nothing more nor less than an aggregation of fields. In .NET it's possible for a structure to "pretend" to be an object, and for each structure type .NET implicitly defines a heap object type with the same fields and methods which--being a heap object--will behave like an object. A variable which holds a reference to such a heap object ("boxed" structure) will exhibit reference semantics, but one which holds a struct directly is simply an aggregation of variables.
I think much of the struct-versus-class confusion stems from the fact that structures have two very different usage cases, which should have very different design guidelines, but the MS guidelines don't distinguish between them. Sometimes there is a need for something which behaves like an object; in that case, the MS guidelines are pretty reasonable, though the "16 byte limit" should probably be more like 24-32. Sometimes, however, what's needed is an aggregation of variables. A struct used for that purpose should simply consist of a bunch of public fields, and possibly an Equals override, ToString override, and IEquatable(itsType).Equals implementation. Structures which are used as aggregations of fields are not objects, and shouldn't pretend to be. From the structure's point of view, the meaning of field should be nothing more or less than "the last thing written to this field". Any additional meaning should be determined by the client code.
For example, if a variable-aggregating struct has members Minimum and Maximum, the struct itself should make no promise that Minimum <= Maximum. Code which receives such a structure as a parameter should behave as though it were passed separate Minimum and Maximum values. A requirement that Minimum be no greater than Maximum should be regarded like a requirement that a Minimum parameter be no greater than a separately-passed Maximum one.
A useful pattern to consider sometimes is to have an ExposedHolder<T> class defined something like:
class ExposedHolder<T>
{
public T Value;
ExposedHolder() { }
ExposedHolder(T val) { Value = T; }
}
If one has a List<ExposedHolder<someStruct>>, where someStruct is a variable-aggregating struct, one may do things like myList[3].Value.someField += 7;, but giving myList[3].Value to other code will give it the contents of Value rather than giving it a means of altering it. By contrast, if one used a List<someStruct>, it would be necessary to use var temp=myList[3]; temp.someField += 7; myList[3] = temp;. If one used a mutable class type, exposing the contents of myList[3] to outside code would require copying all the fields to some other object. If one used an immutable class type, or an "object-style" struct, it would be necessary to construct a new instance which was like myList[3] except for someField which was different, and then store that new instance into the list.
One additional note: If you are storing a large number of similar things, it may be good to store them in possibly-nested arrays of structures, preferably trying to keep the size of each array between 1K and 64K or so. Arrays of structures are special, in that indexing one will yield a direct reference to a structure within, so one can say "a[12].x = 5;". Although one can define array-like objects, C# does not allow for them to share such syntax with arrays.
Use classes.
On a general note. Why not update value b as you create them?
From a c++ perspective I agree that it will be slower modifying a structs properties compared to a class. But I do think that they will be faster to read from due to the struct being allocated on the stack instead of the heap. Reading data from the heap requires more checks than from the stack.
Well, if you go with struct afterall, then get rid of string and use fixed size char or byte buffer.
That's re: performance.

XOR linked list

I recently came across the link below which I have found quite interesting.
http://en.wikipedia.org/wiki/XOR_linked_list
General-purpose debugging tools
cannot follow the XOR chain, making
debugging more difficult; [1]
The price for the decrease in memory
usage is an increase in code
complexity, making maintenance more
expensive;
Most garbage collection schemes do
not work with data structures that do
not contain literal pointers;
XOR of pointers is not defined in
some contexts (e.g., the C language),
although many languages provide some
kind of type conversion between
pointers and integers;
The pointers will be unreadable if
one isn't traversing the list — for
example, if the pointer to a list
item was contained in another data
structure;
While traversing the list you need to
remember the address of the
previously accessed node in order to
calculate the next node's address.
Now I am wondering if that is exclusive to low level languages or if that is also possible within C#?
Are there any similar options to produce the same results with C#?
TL;DR I quickly wrote a proof-of-concept XorLinkedList implementation in C#.
This is absolutely possible using unsafe code in C#. There are a few restrictions, though:
XorLinkedList must be "unmanaged structs", i.e., they cannot contain managed references
Due to a limitation in C# generics, the linked list cannot be generic (not even with where T : struct)
The latter seems to be because you cannot restrict the generic parameter to unmanaged structs. With just where T : struct you'd also allow structs that contain managed references.
This means that your XorLinkedList can only hold primitive values like ints, pointers or other unmanaged structs.
Low-level programming in C#
private static Node* _ptrXor(Node* a, Node* b)
{
return (Node*)((ulong)a ^ (ulong)b);//very fragile
}
Very fragile, I know. C# pointers and IntPtr do not support the XOR-operator (probably a good idea).
private static Node* _allocate(Node* link, int value = 0)
{
var node = (Node*) Marshal.AllocHGlobal(sizeof (Node));
node->xorLink = link;
node->value = value;
return node;
}
Don't forget to Marshal.FreeHGlobal those nodes afterwards (Implement the full IDisposable pattern and be sure to place the free calls outside the if(disposing) block.
private static Node* _insertMiddle(Node* first, Node* second, int value)
{
var node = _allocate(_ptrXor(first, second), value);
var prev = _prev(first, second);
first->xorLink = _ptrXor(prev, node);
var next = _next(first, second);
second->xorLink = _ptrXor(node, next);
return node;
}
Conclusion
Personally, I would never use an XorLinkedList in C# (maybe in C when I'm writing really low level system stuff like memory allocators or kernel data structures. In any other setting the small gain in storage efficiency is really not worth the pain. The fact that you can't use it together with managed objects in C# renders it pretty much useless for everyday programming.
Also storage is almost free today, even main memory and if you're using C# you likely don't care about storage much. I've read somewhere that CLR object headers were around ~40 bytes, so this one pointer will be the least of your concerns ;)
C# doesn't generally let you manipulate references at that level, so no, unfortunately.
As an alternative to the unsafe solutions that have been proposed.
If you backed your linked list with an array or list collection where instead of a memory pointer 'next' and 'previous' indicate indexes into the array you could implement this xor without resorting to using unsafe features.
There are ways to work with pointers in C#, but you can have a pointer to an object only temporarily, so you can't use them in this scenario. The main reason for this is garbage collection – as long as you can do things like XOR pointers and unXOR them later, the GC has no way of knowing whether it's safe to collect certain object or not.
You could make something very similar by emulating pointers using indexes in one big array, but you would have to implement a simple form of memory management yourself (i.e. when creating new node, where in the array should I put it?).
Another option would be to go with C++/CLI which allows you both the full flexibility of pointers on one hand and GC and access to the framework when you need it on the other.
Sure. You would just need to code the class. the XOR operator in c# is ^
That should be all you need to start the coding.
Note this will require the code to be declared "unsafe." See here: for how to use pointers in c#.
Making a broad generalization here: C# appears to have gone the path of readability and clean interfaces and not the path of bit fiddling and packing all the information as dense as possible.
So, unless you have a specific need here, you should use the List you are provided. Future maintenance programmers will thank you for it.
It is possible however you have to understand how C# looks at objects. An instance variable does not actually contain an object but a pointer to the object in memory.
DateTime dt = DateTime.Now;
dt is a pointer to a struct in memory containing the DateTime scheme.
So you could do this type of linked list although I am not sure why you would as the framework typically has already implemented the most efficient collections. As a thought expirament it is possible.

Which is best for data store Struct/Classes?

We have seen lots of discussion in SO regarding the class vs struct in c#. Mostly ended with conclusions saying its a heap/stack memory allocation. And recommending to use structs in small data structures.
Now I have a situation to decide the simple data store among these two choices. Currenlty in our application we have thousands of classes, just acts as simple data stores (only exposed public fields) and they passed among different modules and services.
As per my understanding, I felt it's better to move ahead with struct instead classes for the performance reasons. Because these are simple data structures only act as data stores.
Before proceeding with this, I need some expert advice from the people who have experienced this struggle.
is my understanding correct?
I have seen most ORMs have classes as data stores. So I doubt there should a reason to go ahead with classes instead structs. what would that be?
I would make the choice based on the following criteria
reference type vs value type semantics. If 2 objects are only equal if they are the same object, it indicates reference type semantics => class. If the value of its members defines equality (e.g. 2 DateTimes are equal if both represent the same point in time even if they are 2 distinct objects), value type semantics => struct
Memory footprint of the object. If the object is huge and frequently allocated, making it a struct would consume the stack much faster, hence I'd rather have it as a class. On the contrary, I'd rather avoid the GC penalty for small value types; hence make them a struct.
can you make the object immutable? I find structs great for 'value objects' - from the DDD book.
Would you face some boxing-unboxing penalty based on the usage of this object? If yes, go for class.
A pretty cool, not so well known advantage of Structs over Classes is that there is an automatic implementation of GetHashcode and Equals in structs.
That's pretty useful when keys are required for dictionaries
The struct implementation of GetHashcode and Equals is based on the binary content of the struct instances + reflection for the reference members (like String members and other instances of classes)
So the following code works for GethashCode/Equals :
public struct Person
{
public DateTime Birthday { get; set; }
public int Age{ get; set; }
public String Firstname { get; set; }
}
class Program
{
static void Main(string[] args)
{
Person p1 = new Person { Age = 44, Birthday = new DateTime(1971, 5, 24), Firstname = "Emmanuel" };
Person p2 = new Person { Age = 44, Birthday = new DateTime(1971, 5, 24), Firstname = "Emmanuel" };
Debug.Assert(p1.Equals(p2));
Debug.Assert(p1.GetHashCode() == p2.GetHashCode());
}
}
Both assertions succeed when Person is a struct
Both assertions fail if Person is a class instead of a struct
Reference :
https://msdn.microsoft.com/en-Us/library/2dts52z7%28v=vs.110%29.aspx
Regards, best coding
structs should be defined immutable where in classes should not. If you think your objects are going to be small and immutable you can go ahead with making them structs or else let them be classes.
I can never really seem to remember, exactly how structs are different, but they are. In subtle ways. In fact, sometimes they come and bite you.
So. Unless you know what you are doing, just stick to classes.
I know this sounds a little newbie. I know I should right now go and look up the differences and display them here - but that has already been done by others. All I'm saying is that adding a different type of objects creates a semantical burden, a bit of extra complexity that you are wise to consider carefully.
If I remember correctly, one of the biggest problem is the value semantics of structs: Passing them around will result in different objects (as they get passed by value). If you then change some field in one place, beware that in all other places the field did not get changed! That is why everyone is recommending immutability for structs!
EDIT: For the case you are describing, structs won't work!
A class object has the advantage that it's possible to pass around a reference to it, with the scope and lifetime of such a reference being unlimited if it reaches outside code. A struct has the advantage that while it's possible to pass around short-lived references to them, it's not possible to pass around perpetual promiscuous references. This helps avoid having to worry about whether such references exist.
Some people have suggested that data holders which are mutable should not be structs. I emphatically disagree. Entities which exists for the purpose of holding data should, in many cases, be structs, especially if they are mutable. Eric Lippert has posted many times that he considers mutable value types evil (search under tags "mutable" and "struct"). It is certainly true that .net allows certain things to be done with mutable structs which it shouldn't, and doesn't conveniently allow some things that it should, but POD ("Plain Old Data") structs which have no mutating methods, but instead expose their entire state via public fields, have a very useful consistency in their behavior which is not shared with any other data type. Using a POD struct may confuse someone who isn't familiar with how they work, but will make the program much more readable by anyone who does.
Consider, for example, the following code, assuming EmployeeInfoStruct contains nothing but value types and immutable class types like String:
[employeeInfoStruct is a struct containing the following field]
public Decimal YearlyBonus;
[someEmployeeContainer is an instance of a class which includes the following method]
EmployeeInfoStruct GetEmployeeInfo(String id); // Just the signature--code is immaterial
[some other method uses the following code]
EmployeeInfoStruct anEmployee = someEmployeeContainer.GetEmployeeInfo("123-45-6789");
anEmployee.YearlyBonus += 100;
Eric Lippert complains that the above code will alter the value in anEmployee, but that change won't have any effect on the container. I would suggest that's a good thing--anyone who knows how structs work could look at the above code and know writes to a struct variable will affect that variable, but won't affect anything else unless the program later uses some other method (perhaps SetEmployeeInfo) to store that variable someplace.
Now replace EmployeeInfoStruct with EmployeeInfoClass, which has a read/write property of type YearlyBonus. Using just the information above, what can one say about the the relationship between writes to someEmployeeContainer and anEmployee? Depending upon the implementations of anEmployee's class (which, unless EmployeeInfoClass is sealed, might or might not actually be EmployeeInfoClass) and someEmployeeContainer, the relationship between the objects could be anything. Writes to one might:
Have no effect on the other
Update the other in 'natural' fashion
Corrupt the other in some arbitrary way
With structs containing nothing but fields of either value types or immutable classes, the semantics are always going to be #1. One doesn't have to look at the code for the struct itself, nor the code of the container, to know that. By contrast, if the anEmployee.Salary or someEmployeeContainer.GetEmployee is virtual, it's impossible to really know what the semantics will be.
It's important to note that, if structs are large, passing them by value or returning them from functions can be expensive. It's generally better to pass large structs as ref parameters when possible. Although the built-in collections really don't do a good job of facilitating such usage, it can make using a hundreds-of-bytes struct cheaper than using a class.
The comment about structs being immutable is correct. And this is where it can bite you. You can define structs with field setters, but when you change a field value a new instance is created. So if you hold a reference to the old object it will still reference the old value. I don't like using mutable stucts for this reason as this can produce subtle and complex bugs (especially if you use complex compound statements).
On the other hand, there are lots of good reasons for using classes with immutable state also (think string).
I remember one advice given on MSDN that struct should not be larget than 16 or 21 bytes. Looking for the link, but can't find it yet.
The main implication was that once you have a string in your data type - make it a class without thinking. Otherwise the struct shouldn't hold much.
I think you have the right idea. Structs are made to mimic data-types. They are value driven not reference based. If you look at the MSDN documentation for most of the base data classes (int, double, decimal, ect.) they are all based on structs. That being said however, structs should not be overused for that very same reason. Room to store all everything in that struct is allocated as soon as it is instantiated, where as classes just allocate room for a reference to everything inside. If the data is in small enough chunks where this is not a problem than structs are the way to go. If this is an issue go with classes. If you don't know than it might just be best to stick with what you are familiar with.
If you have low latency requirements and A LOT of objects slow garbage collections can be a problem. In that case struct can be very helpful because the garbage collector does not need to scan through a hierarchy of value types if the value types does not contain any reference types.
You can find a benchmark here: http://00sharp.wordpress.com/2013/07/03/a-case-for-the-struct/

Object Copy simple question?

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.

when is it ok to use a structure rather than a class

In a recent project I was working I created a structure in my class to solve a problem I was having, as a colleague was looking over my shoulder he looked derisively at the structure and said "move it into a class".
I didn't have any argument for not moving it into a class other than I only need it in this class but this kind of falls down because couldn't I make it a nested class?
When is it ok to use a structure?
You should check out the value type usage guidelines: http://msdn.microsoft.com/en-us/library/y23b5415(vs.71).aspx
The article lists several important points but the few that I feel are the most valuable are the following
Is the value immutable?
Do you want the type to have value semantics?
If the answer to both questions is yes then you almost certainly want to use a Structure. Otherwise I would advise going with a class.
There are issues with using structures with a large amount of members. But I find that if I consider the two points above, rarely do I have more than the recommended number of members / size in my value types.
MSDN has a good guidelines document to cover structure usage. To summarize:
Act like primitive types.
Have an instance size under 16 bytes.
Are immutable.
Value semantics are desirable.
Otherwise, use a class.
You should always use a Class as your first choice, changing to Structure only for very specific reasons (as others have already outlined).
Depending on how much you "only need it in this class", you might be able to avoid the nested type completely by using an anonymous type; this will only work within a single method:
Public Class Foo
Public Sub Bar
Dim baz = New With { .Str = "String", .I = 314 }
End Sub
End Class
you can't (readily--there are a few things you can do with generics) move the instance baz outside of the Sub in a typesafe manner. Of course an Object can hold anything, even an instance of an anonymous type.
I think structures are great if you need copy the object or do not want it to be modified by the passed function. Since passed functions can not modify the originally passed structure instead got a new copy of it, this can be a life saver. (unless they passed as ByRef obviously) and can save you trouble of deep copy craziness in .NET or implementing pain of an ICloneSomething implementation.
But the general idea is defining a custom data structure in a more semantic way.
About moving to a class, if you are moving into a class where it'll be part of a class, generally this is good practice since your structure is 99% of the time related with one of you classes not related with a namespace.
If you are converting it to a class then you need to consider "is it defining a data strcuture" and "is it expensive?" since it's gonna be copied all over the place, "do you want to get affected by modifications done by the passers?"
The usage guidelines referenced by Marc and Rex are excellent and nicely cover cases where you aren't sure which one you would want. I will list some use cases where use of a struct is a requirement.
When you need to set the layout of the fields in memory
Interop with unmanaged code.
When you want to make Unions.
You need a fixed size buffer inlined.
You want to be able to do the equivalent of a reinterpret_cast with relative safety (so long as the struct does not contain any fields which are themselves reference types.
These are normally edge cases and (with the exception of interop) not recommended practices unless their use is necessary for the success of the project/program.

Categories

Resources