What are the most common or vicious mistakes when experienced C++ programmers develop in C#?
views:
688answers:
13- the difference between
struct
andclass
in the two - the difference between a
using
alias and atypedef
- when do my objects get collected? how do I destroy them now?
- how big is an
int
? (it is actually defined in C#) - where's my linker? (actually, Mono does have a full AOT linker for some scenarios)
- RAII vs IDispose
- value type vs ref type (struct vs class, boxing and unboxing, etc.)
I've seen many C++ coders code in a COM style in C#, trying to deal with the inadequacies of the language. C# provides lots of a type safe support for your enums and there are usually nicer APIs then P/Invoking back down to C++.
The other thing I've seen catch most people out is that C# generics are not templates.
Thinking that "garbage collection" = "I never have to worry about object lifetime at all". For instance, opening a FileStream
and forgetting to close it.
Or:
- Allocating a lot of objects
- Putting them in a big global dictionary (usually after "I know, I'll make a cache")
- Wondering why the application's memory usage always goes up and never down ("but it's supposed to garbage collect!")
Confusing "pass by reference" and "reference type":
void GetAnArray(int input, ref string[] output);
(Compare with C++: void getAnArray(int input, std::vector<std::string>& output);
)
Writing the full namespace each time.
This is fine in C++ when you're typing std::this
or boost::that
. Not so great in C# when you repeat System.Windows.Forms.Whatever
all over the place.
using Hungarian Notation and other C++ naming conventions
private int m_iMyIntField;
class CWidget { ... }
- Using structs in favour for classes all the time.
- Using in, out and ref parameters all the time (This is a result of point 1).
- Using int values as error conditions instead of using exceptions
- Using the virtual keyword instead of override keyword.
- Thinking that char is an 8 bit signed value.
Incidentally, the C# compiler has a number of heuristics in it for helping out the experienced C++ programmer who is a novice C# programmer. For example, if you say
int x[];
the compiler will helpfully point out that the [] is a part of the type in C#, so you probably meant
int[] x;
C# also allows things like putting unnecessary semicolons at the end of a class declaration so that C++ programmers who are in that habit don't get bitten by it.
One that got me, and I believe a lot of non C++ people too, was leaking memory due to registered events keeping an object alive.
IDisposable grated to begin with (and still does if I'm honest) but was pretty obviously going to be a difference when going from native to managed code so it is not something I'd expect C++ developers to actually fall foul of, they just won't like it.