In C++, we have Copy Constructor, Destructors, overloaded = which are together called copy control.
My questions are:
Is copy constructor used in C# for initializing objects when passed to a function as argument or when initializing (not assigning) or when returning an object from a function as in C++?
Does an implicitly overloaded = operator function gets called when we assign (not initialize) any object to another object of the same type?
No: reference objects are passed by reference, while value objects are copied byte-for-byte. You can make your own "copy constructors", but you would be responsible for calling them explicitly.
You cannot overload the assignment operator
In fairness to C#, none of the intricacies of the C++ copy control are necessary because of the underlying garbage-collected memory model. For example, you do not need to control the ownership of dynamically allocated objects when copying objects, because you are free to have as many references to dynamic objects as you wish.
In C# you cannot overload the assignment operator.
Destructors don't really make sense in a managed memory world (most of the time). There is actually an equivalent (finalizers) but you should very rarely need to utilize them.
Copy constructors are made for certain classes, but it's not done nearly as often as in C++. It will never be called implicitly by the language, it will only be used when you manually call it.
No. If you want to provide copying mechanism, you do this by implementing the ICloneable interface: http://msdn.microsoft.com/en-us/library/system.icloneable.aspx
C# has no concept of a copy constructor, nor of overloading operator=. In C# objects just exist and you use handles to them in your code. Handles can be copied "by value" to be used throughout your code, but that's a so-called "shallow" copy, the object itself is still the same, they all point to the same memory (indirectly).
Copy constructors are akin to deep copying in the managed world, and you can achieve that through ICloneable, but it's completely manual and up to the object's implementation to write it. You can also achieve it through serialization (the boost way) or through any manner of indirect ways.
As a final point, since object lifetimes are non-deterministic (they die when the GC arbitrarily decides they should die), there's no such thing as destructors either. The closest thing are finalizers (called non-deterministically when your object gets collected) and the IDisposable pattern (along with using) which give you a semblance of control over finalization. Needless to say they are rarely used.
Edit: I should point out that, while copy constructors have no equivalent, you do have "type casting" constructors through implicit, the precise name escapes me at the moment.
Related
Does it make any sense to use a struct instead of a reference type in case of CancellationToken?
I see one possible disadvantage, it will be copied all the way down in methods chain as I pass it as a parameter.
In the same time, as far as it is struct, it might be allocated and disposed faster.
If we want to make it immutable, we can use readonly properties or private setters.
So what was an idea behind it?
There is an article that describes the .NET Cancellation design here which is worth a read. In relation to your question, the following is asked in the comments:
Just out of interest, why is the CancellationToken a value type?
and the questioner proposes an alternative implementation with a single shared instance of CancellationToken as a reference type.
And the response by Mike Liddell:
This would certainly work and is largely equivalent (and we implemented it this way during early prototyping), but we went with the current design for two particular reasons:
– only one class instance per CTS/Token, hence less GC pressure.
– we consolidate all of the state and most of the logic onto CTS. The split arrangement was a somewhat more convoluted.
I would note that the current value type implementation is exactly the same size as a reference so there isn't any additional copying overhead. It also prevents some additional boilerplate null checks in user-code, especially when making the token an optional parameter.
Does it make any sense to use a struct instead of a reference type in case of CancellationToken?
Yes.
I see one possible disadvantage, it will be copied all the way down in methods chain as I pass it as a parameter.
That is not a disadvantage. A cancellation token is reference-sized. Why would there be a disadvantage of passing a reference-sized struct vs passing a reference? This objection doesn't make sense. Please explain why you think this is a "disadvantage".
In the same time, as far as it is struct, it might be allocated and disposed faster.
That's correct, but the actual win is more likely that a reference-sized struct that wraps a reference does not increase collection pressure. Many of the design and implementation decisions in the .NET framework are designed to ensure that collection pressure is not increased too much by framework code.
So what was an idea behind it?
It's a small type that is logically a value; why shouldn't it be a value type?
For example, wouldn't this type:
https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector2.aspx
... having public mutable fields like this:
https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector2.x.aspx
... single-handedly make consuming F# code's immutability efforts kind of useless?
PS: performance must be preserved, no wrapping or dynamic instantiation of throw-away values.
PPS: I did some research and suspect the answer (negative) but would appreciate some input. It seems like a typical problem when not implementing everything in F# from scratch.
For collections of structs, this is not an issue. The collection remains immutable irrespective of the struct's members, since getting the struct from the collection returns a copy. Altering this copy does not alter the collection's contents.
Elsewhere, structs can be used to write wrappers without additional GC load. This requires to create methods for all features you want to keep and have them call the original methods. Unless the JIT doesn't inline the calls, this shouldn't cost performance. However, when wrapping reference types, this will create an empty default constructor on the wrapper type, resulting in a null reference if this constructor is called.
As a side note, I wouldn't recommend using vector classes from outside F#, since they are not unit-of-measure aware. In my experience, most vectors can be assigned physical units, which makes code safer and more readable.
You are correct, the short answer is no. However, at least in the case of the Vector2 class you show, many of the operations are implemented in an immutable fashion when you use the static versions of the methods. For example
var vecB = Vector2.Normalize(vecA);
is an immutable call. Unless the libraries you are using support some kind of immutability, you are stuck with having to implement the immutable functionality you want to have.
F# has a design goal of being a hybrid of mutable and immutable content so that it can access the rich functionality of .NET libraries when needed.
I am developing mono and .net applications. I have some basic questions regarding the best practices.
If I need to create an unmanaged object just to be used once (may be pass to a method or invoke one of it's method) and don't need it later, should I assign it to a variable first and then use it so that I can dispose it (or may be assign variable in a using() block) or should I just use like new Class().Method(), in order for GC to be able to collect it? What is the best practice?
Do I need to dispose of objects which has only a local scope of a method or is it enough if I dispose of object that are properties of the class (global)?
I have a Class A and a Class B. An object of B is created in some method M of Class A. This object (of class B) has another method M2 which invokes a second method in Class A, M3. So structure is as below
Class A
{
void M()
{
var b = new B();
}
public string M3()
{
return "OK";
}
}
Class B
{
void M2()
{
Console.WriteLine(new A().M3();
}
}
Will this create a cyclic reference a stop GC from collecting these two objects?
What are the other general principles for good Memory efficient programming?
This question has a significant risk of becoming "too broad", i.e. off-topic for StackOverflow. That said, some brief answers:
If I need to create an unmanaged object just to be used once (may be pass to a method or invoke one of it's method) and don't need it later… What is the best practice?
Best-practice for using any unmanaged object is to wrap it in an instance of SafeHandle. Of course, most common unmanaged objects you'd have to deal with are already wrapped by .NET, either in some custom implementation of IDisposable (e.g. StreamReader), or in newer framework code, as a SafeHandle subclass.
But when you are dealing with your own unmanaged objects that .NET has no knowledge of, you'll want to follow .NET's example and use SafeHandle.
Do I need to dispose of objects which has only a local scope of a method or is it enough if I dispose of object that are properties of the class (global)?
If you create the object, and you have not passed it to some other code for it to own, and you are not going to return it from the method, then you need to dispose it. You do need to dispose objects which are referenced only within a method.
Typically you would use the using statement to do this.
…Will this create a cyclic reference a stop GC from collecting these two objects?
Ignoring for a moment that your code example wouldn't compile, nor contains any reference cycles… :)
Unlike some memory management schemes, such as ref-counting, .NET's garbage collection does not have any issue with cyclical references at all. An object is determined to be collectable or not based on whether it is reachable from a root reference. Two unrooted objects which reference each other are still neither reachable from a root reference and so are both collectable.
What are the other general principles for good Memory efficient programming?
That's definitely too broad for StackOverflow. Even in the GC-based system .NET uses, there a lot of fine details that one can concern oneself with. The basic system eliminates a number of common programming errors, but it has its own idiosyncratic behaviors that are in some cases important to understand.
Some time spent browsing MSDN and web articles on the topic will help you learn more about garbage collection, in .NET and in general. If and when you have other specific questions, please feel free to post them on StackOverflow.
I'm having trouble creating copies of my class instances from a dictionary of templates. It appears that MemberwiseClone() leaves some fields referenced to the dictionary's template fields. I'd like to be able to see if that's so in a convenient way, like Visual Studio's DataTips provide.
Is there a way to find out if an instance of a reference type object (or its fields) is referencing another instance of the same type (after memberwise cloning)?
The rule is that any value type will be copied and any reference type will only copy the reference. It is a shallow copy.
If that is not the behaviour that you want then you need to roll your own clone method.
You are probably talking about a deep copy, in which case this will tell you what you need to know: How do you do a deep copy of an object in .NET (C# specifically)?
As for counting the number of references to an instance, Eric Lippert says that C# does not do reference counting C# - Get number of references to object so again you would have to roll your own. But I don't think that is what you want to do.
You could use a memory profiler for manually checking the references. See .NET Memory Profiling Tools.
One "feature" of Java is that there's really only one non-primitive type: an object reference, which may be used in all sorts of ways. While that makes the framework easy to implement, it means that the type of a variable is insufficient to describe its meaning. While .net improves on Java in many ways, it shares that fundamental weakness.
For example, suppose an object George has a field Bob of type IList<String> [or, for Java, list<string>]. There are at least five fundamentally different things such a field could represent:
It holds a reference to an object holding a set of strings to which it will never allow any changes. If item #5 of that list is "Barney", then item #5 on that list will never be anything other than "Barney". In this scenario, `Bob` encapsulates only immutable aspects of the list. Further, the reference may be freely shared to any code that's interested in that aspect of George's state.
It holds a reference to an object holding a set of strings which may be modified by anyone holding a reference, but no entity with a reference to that object will modify the list nor allow it to be exposed to anything that might do so. In other worse, while the list would allow its contents to be changed, nothing will in fact ever alter those contents. As above, `Bob` encapsulates only immutable aspects of the list, but `George` is responsible for maintaining such immutability by exposing the reference only to code that can be trusted not to modify the list.
It holds the only reference, anywhere in the universe, to an object holding a set of strings which it modifies at will. In this scenario, `Bob` encapsulates the *mutable state* of the list. If one copies `George`, one must make a new list with the same items as the old, and give the copy a reference to that. Note also that `George` cannot pass a reference to any code that might persist the reference, whether or not that code would try to modify the list.
It holds a reference to a list which is "owned" by some other object, which will be used either to add items to the list for the other object's benefit, or to observe things the other object has put in the list for `George`'s benefit. In this scenario, `Bob` encapsulates the *identity* of the list. In a correct clone, `Bob` must identify the *same list* as in the original.
It holds a reference to a list which it owns, and which will be mutated, but to which some other objects also hold a reference (perhaps so they can add things to the list for `George`'s benefit, or perhaps so they can see things `George` does with the list). In this scenario, `Bob` encapsulates *both mutable state and identity*. The existence of a field which encapsulates both aspects means that *it is not possible to make a semantically-correct copy of `George` without the cooperation of other objects*.
In short, it's possible for Bob to encapsulate the list's mutable state, its identity, both, or neither (immutable state, other than identity, is a 'freebie'). If it encapsulates only mutable state, a semantically-correct copy of George must have Bob reference a different list which is initialized with the same contents. If it encapsulates only identity, a semantically-correct copy must have Bob reference the same list. If it encapsulates both mutable state and immutble state, George cannot be properly cloned in isolation. Fields that do neither may be copied or not, as convenient.
If one can properly determine which fields encapsulate the referenced objects' mutable states, which ones encapsulate identity, and which ones both, it will be obvious what a semantically-correct cloning operation should do. Unfortunately, there's no standard convention in the Framework for categorizing fields in such fashion, so you'll have to come up with your own method and then a cloning scheme that uses it.
I've been playing around with c++ lately and wondered why there were so many global functions. Then I started thinking about programming in c# and how member functions are stored, so I guess my question is if I have a:
public class Foo {
public void Bar() { ... }
}
and then I do something silly like adding 1,000,000 Foo's to a list; does this mean I have 1,000,000 Foo objects sitting in memory each with there own Bar() function? Or does something much more clever happen?
Thanks.
Nope, there is only one instance. All instances of a class point to an object that contains all the instance methods that take an implicit first parameter affectionately called this. When you invoke an instance method on an instance the this pointer for that instance is passed as the first parameter to that method. That is how the method knows all the instance fields and properties for that instance.
For details see CLR via C#.
This is, of course, complicated by virtual methods. CLR via C# will spell out the distinction for you and is highly recommended if you are interested in this subject. Either way, there is still only one instance of each instance method. The issue is just how these methods are resolved.
An instance method is simply a static method with a hidden this parameter.
(virtual methods are a little more complicated)
In C++ a member function doesn't normally require any per-object storage (an exception - virtual functions - is discussed in the next paragraph). Normally, at each point where the function is used the compiler generates CPU-specific machine code to directly call that function, and for inline functions the call may be avoided and the function's affect may be optimally integrated into the caller's code (which can be ~10x faster for small functions such as "getters and setters" that simply read or write one member variable).
For those classes that have one or more virtual functions, each object will have one extra pointer to a per-class table of function pointers and other information. Thus, each object grows by the size of a pointer - typically 4 or 8 bytes.
Addressing your original observation: C++ has more non-member functions (usually in the std namespace), but a namespace serves this purpose better than a class anyway. Indeed, namespaces are effectively logical interfaces for "static" functions and data that can span many "physical" header files. Why should the logical API of a program be compromised by considerations related to physical files and their implications to build times, file-modification-timestamp triggered make tools etc? In trivial cases where the namespace is in one header, C++ could use a class or struct to scope the same declarations, but that's less convenient as it prevents the use of namespace aliases, using namespaces, and Koenig lookup for implicitly searching namespaces matching a function arguments' namespaces - forcing very explicit prefixing at every point of use. It also gives the false impression that the user is intended to instantiate an object from the content.