Most common mistakes C# developers make
While working with (young) C# Programmers
I’ve noticed that some mistakes are being repeated by almost every one of them.
These are mostly the mistakes, which once you point them, are quite easy to
remember. However, if a developer is not aware of them, they can cause many
problems with the efficiency and quality of the developed software. Therefore,
I decided to gather the 8 most common mistakes made.
1. String concatenation instead of StringBuilder
String concatenation works in such a way
that every time when you add something to a string, a new address in the memory
is being allocated. The previous string is copied to a new location with the
newly added part. This is inefficient. On the other hand we have StringBuilder
which keeps the same position in the memory without performing the copy
operation. Thanks to the strings’ appending by means of StringBuilder the
process is much more efficient, especially in case of hundreds of append
operations.
1
2
3
4
5
6
7
|
//INCORRECT List values = new
List(){"This
","is ","Sparta ","!"}; string
outputValue
= string.Empty; foreach
(var
value in values) { outputValue += value; } |
1
2
3
4
5
6
|
//CORRECT StringBuilder outputValueBuilder = new
StringBuilder(); foreach
(var
value in values) { outputValueBuilder.Append(value); } |
2. LINQ – ‘Where’ with ‘First’ instead of FirstOrDefault
A lot of programmers find a certain set
of elements by means of ‘Where’ and then return the first occurrence. This is
inappropriate, because the ‘First’ method can be also applied with the ‘Where’
condition. What’s more, it shouldn’t be taken for granted that the value will
always be found. If “First” is used when no value is found, an exception will
be thrown. Thus, it’s better to use FirstOrDefault instead. When using
FirstOrDefault, if no value has been found, the default value for this type
will be returned and no exception will be thrown.
1
2
3
|
//INCORRECT List numbers = new
List(){1,4,5,9,11,15,20,21,25,34,55}; return
numbers.Where(x
=> Fibonacci.IsInFibonacciSequence(x)).First(); |
1
2
|
//PARTLY CORRECT return
numbers.First(x
=> Fibonacci.IsInFibonacciSequence(x)); |
1
2
|
//CORRECT return
numbers.FirstOrDefault(x
=> Fibonacci.IsInFibonacciSequence(x)); |
3. Casting by means of ‘(T)’ instead of ‘as (T)’ when possibly
not castable
It’s common that
software developers use simple ‘(T)’ casting, instead of ‘as (T)’. And usually
it doesn’t have any negative influence because casted objects are always
castable. Yet, if there is even a very slight probability that an object can be
under some circumstances not castable, „as (T)” casting should be used.
1
2
|
//INCORRECT var woman = (Woman)person; |
1
2
|
//CORRECT var woman = person as
Woman; |
4. Not using mapping for rewriting properties
There are a lot
of ready and very powerful C# mappers (e.g. AutoMapper). If a few lines
of code are simply connected with rewriting properties, it’s definitely a place
for a mapper. Even if some properties aren’t directly copied but some
additional logic is performed, using a mapper is still a good choice
(mappers enable defining the rules of rewriting properties to a big extend).
5. Incorrect exceptions re-throwing
C# programmers usually forget that when
they throw an exception using „throw ex” they loose the stack trace. It is then
considerably harder to debug an application and to achieve appropriate log
messages. When simply using „throw” no data is lost and the whole exception
together with the stack trace can be easily retrieved.
01
02
03
04
05
06
07
08
09
10
|
//INCORRECT try { //some code that can
throw exception [...] } catch
(Exception
ex) { //some exception logic
[...] throw
ex; } |
01
02
03
04
05
06
07
08
09
10
|
//CORRECT try { //some code that can
throw exception [...] } catch
(Exception
ex) { //some exception logic
[...] throw; } |
6. Not using ‘using’ for objects disposal
Many C# software developers don’t even
know that ‘using’ keyword is not only used as a directive for adding
namespaces, but also for
disposing objects. If you
know that a certain object should be disposed after performing some operations,
always use the ‘using’ statement to make sure that the object will actually be
disposed.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
//the below code: using(SomeDisposableClass
someDisposableObject = new SomeDisposableClass()) { someDisposableObject.DoTheJob(); } //does the same as: SomeDisposableClass someDisposableObject
= new SomeDisposableClass(); try { someDisposableObject.DoTheJob(); } finally { someDisposableObject.Dispose(); } |
7. Using ‘foreach’ instead of ‘for’ for anything else than
collections
Remember that if
you want to iterate through anything that is not a collection (so through e.g.
an array), using the ‘for’ loop is much more efficient than using the ‘foreach’
loop.
8. Retrieving or saving data to DB in more than 1 call
This is a very common mistake,
especially among junior developers and especially when using ORMs like Entity
Framework or NHibernate. Every DB call consumes some amount of time and
therefore it’s crucial to decrease the amount of DB calls as much as possible.
There are many ways to do so:
§ Using
fetching (Eager Loading)
§ Enclosing
DB operations in transactions
§ In
case of a really complex logic, just moving it to the DB by building a stored
procedure
It goes
without saying that there are hundreds of other types of mistakes made by C#
programmers. If you know any interesting ones or you want to share your opinion
about the subject, feel free to leave a comment below!
No comments :
Post a Comment