55

To cut a long story short: I find the Java antipatterns an indispensable resource. For beginners as much as for professionals. I have yet to find something like this for C#. So I'll open up this question as community wiki and invite everyone to share their knowledge on this. As I am new to C#, I am strongly interested in this, but cannot start with some antipatterns :/

Here are the answers which I find specifically true for C# and not other languages.

I just copy/pasted these! Consider throwing a look on the comments on these as well.


Throwing NullReferenceException

Throwing the wrong exception:

if (FooLicenceKeyHolder == null)
    throw new NullReferenceException();

Properties vs. public Variables

Public variables in classes (use a property instead).

Unless the class is a simple Data Transfer Object.


Not understanding that bool is a real type, not just a convention

if (myBooleanVariable == true)
{
    ...
}

or, even better

if (myBooleanVariable != false)
{
    ...
}

Constructs like these are often used by C and C++ developers where the idea of a boolean value was just a convention (0 == false, anything else is true); this is not necessary (or desirable) in C# or other languages that have real booleans.


Using using()

Not making use of using where appropriate:

object variable;
variable.close(); //Old code, use IDisposable if available.
variable.Dispose(); //Same as close.  Avoid if possible use the using() { } pattern.
variable = null; //1. in release optimised away.  2. C# is GC so this doesn't do what was intended anyway.
Community
  • 1
  • 1
exhuma
  • 20,071
  • 12
  • 90
  • 123
  • 2
    Well... this was *exactly* what I tried to avoid. The question linked as "duplicate" contains many common OO "bad practices". I've been developing for more than 10 years now and these are not new to me. What I expected in this case, were specific **C#** anti-patterns. – exhuma Oct 07 '09 at 07:55
  • 3
    The Java "antipatterns" you link to are not antipatterns (e.g ineffective and/or counterproductive design patterns), but bad coding practices, like most of the answers to your question. Like design patterns, antipatterns are language agnostic. – comichael Oct 12 '09 at 04:48
  • good point. If you consider "Design Patterns" there are those that are language agnostic, but then, some make more sense in a language than others. Others may be irrelevant for a given language, if the language itself offers a solution to the given problem. So I assume, that you could also find Antipatterns which are more relevant to C# than other languages. Reading the same good/bad practices over-and-over again is getting boring ;) – exhuma Oct 15 '09 at 12:12
  • Dispose does not always include Close by the way. It does in most .net classes and it's common sense, but it's nowhere explicitly implied. – Michael Stum Dec 23 '09 at 06:05

38 Answers38

62

Rethrowing the exception incorrectly. To rethrow an exception :

try
{
    // do some stuff here
}
catch (Exception ex)
{
    throw ex;  // INCORRECT
    throw;     // CORRECT
    throw new Exception("There was an error"); // INCORRECT
    throw new Exception("There was an error", ex); // CORRECT
}
rein
  • 32,967
  • 23
  • 82
  • 106
  • 31
    `catch (Exception ex)` is an anti-pattern in itself. – Joren Oct 07 '09 at 06:27
  • Unless you're doing some logging or similar and then re-throwing it – thecoop Oct 08 '09 at 13:18
  • 18
    @Joren, catch (Exception ex) without throw is an anti-pattern ... there are lot's of valid cases to catch the general exception type if you throw back (like, logging, throwing a new exception type, doing a rollback on some resources, etc.). But of course the rules vary for applications, libraries, plugins etc. – Pop Catalin Oct 08 '09 at 14:09
  • catch (Exception ex) is perfectly valid for web applications. might be other cases too. – Egor Pavlikhin Oct 08 '09 at 15:55
  • aaah throw new Exception("There was an error", ex); so it shows the original exception as the inner exception, nice! – Carlo Oct 08 '09 at 15:59
  • 5
    throw new Exception("There was an error") might be perfectly valid if you want to hide the original error (e.g. a library), perhaps security-related. – erikkallen Oct 10 '09 at 12:04
40

GC.Collect() to collect instead of trusting the garbage collector.

Adriano Carneiro
  • 57,693
  • 12
  • 90
  • 123
Andrew Keith
  • 7,515
  • 1
  • 25
  • 41
  • 12
    And failing to wait for pending finalizers to complete, in the rare situations where you do want to force a collection. – Eric Lippert Oct 07 '09 at 15:16
  • Not really. I had situations were i got an reproducable OutOfMemoryException that was gone after calling GC.Collect() now and then. GC seems to be broken. – Rauhotz Oct 07 '09 at 20:25
  • broken vs non deterministic. If you release a whole lot of references and suddenly need it again, then this is probably a candidate for calling it manually. – Spence Oct 07 '09 at 20:35
  • I vote for non deterministic, at least I would never want to determine what I would do now, if I was the GC. It's implementation details one should never depend on. Isn't there even a two-phase-approach in garbace collecting? Maybe we should replace all 'GC.Collect;' by 'GC.Collect(); GC.Collect();' – Simon D. Oct 07 '09 at 20:51
  • If the GC prefers to throw an OutOfMemoryException instead of just doing its work, which is collecting garbage (like via GC.Collect) and giving me the requested memory, i call that broken. – Rauhotz Oct 07 '09 at 21:13
  • 4
    You can get an OutOfMemoryException for having fragmented references or for requesting more memory then you have on your system. Do you, by any chance, have your page file size fixed? I mean if you think you can write a better garbage collector than Microsoft I say go for it and then get them to buy it from you. – Matthew Whited Oct 08 '09 at 13:10
  • 6
    There are valid use cases for GC.Collect(), but almost none in typical applications. You need a special use for .Net to call GC.Collect() (like a Game engine, after loading a level, so the GC won't start in the middle of the level doing a full collect, collecting previous level allocated objects) or near real time applications, where GC behaviour needs to be somewhat controlled and predictable, or server applications when you know you will run idle for a certain period and use that opportunity to collect. – Pop Catalin Oct 08 '09 at 14:16
  • @Pop Catalin -- All valid use cases... What exactly is a "normal application"? All those seem like prett "normal" applications to me. – Robert Fraser May 25 '10 at 10:22
  • @Robert Fraser, I've never used the word "normal" but "typical" meaning what the .Net developers write on a day to day basis as of now, but things will change in the future, and "typical" will include a larger spectrum than it does now. – Pop Catalin May 29 '10 at 17:24
30

I see this one way too much, both in Java and C#...

if(something == true){
  somethingelse = true;
}

with bonus points if it also has

else{
  somethingelse = false;
}
sstewart
  • 51
  • 2
  • 4
  • 4
    Without the bonus it's not that painful (only the "== true") – ripper234 Oct 07 '09 at 06:16
  • 9
    With the first case, consider the case of something = false and somethingelse = true. You shouldn't refactor to somethingelse = something – vanja. Oct 07 '09 at 06:20
  • I agree with rupper234. It could actually improve readability in some cases. – Egor Pavlikhin Oct 07 '09 at 06:23
  • We can make this better: if (something == true) { somethingelse = true; } else { somethingelse = false; } return somethingelse; – Wedge Oct 07 '09 at 10:15
  • other than this being verbose it is not a 'bug' as such. – Johnno Nolan Oct 08 '09 at 15:17
  • saw this today on The Daily WTF http://thedailywtf.com/Articles/The-Clever-Coder.aspx – sstewart Oct 09 '09 at 05:11
  • @Tordek -- I've NEVER seen that construct used. I'd argue the if-statement version is more readable. – Robert Fraser May 25 '10 at 10:24
  • -1. It's more verbose than necessary, but beside that, there is nothing wrong with it. – Joh May 25 '10 at 11:49
  • @Robert Fraser: Ah, I was thinking in C. A more appropiate (yet nonexistant in C#) would be `||=`. Or the longhand it'd represent: `somethingelse = something || somethingelse`. (This is of course assuming 2 things: `somethingelse` has a value, and the `else` isn't used; otherwise, `somethingelse = something` is enough/) – Tordek May 27 '10 at 08:14
25
using Microsoft.SharePoint;

'nuff said

Rubens Farias
  • 57,174
  • 8
  • 131
  • 162
22

I see following code a lot:

if (i==3)
       return true;
else
       return false;

should be:

       return (i==3);
Benny
  • 8,547
  • 9
  • 60
  • 93
17

Insulting the law of Demeter:

a.PropertyA.PropertyC.PropertyB.PropertyE.PropertyA = 
     b.PropertyC.PropertyE.PropertyA;
leppie
  • 115,091
  • 17
  • 196
  • 297
  • +1, but sadly in some cases (especially with static classes) it can seem hard to get away from... For instance, recently I wrote this: `this.Left = Screen.AllScreens[target].Bounds.X` – Matthew Scharley Oct 07 '09 at 05:33
  • @matthew: it is not so much the left hand side that bothers me. The assignment/mutation is the problem. Call you tell what you are modifying? – leppie Oct 07 '09 at 05:39
  • I'm setting the left side of my form to the left edge of a target screen. In reality, `Screen.AllScreens` is aliased to a local variable because I didn't want to type full qualification everywhere, but that only shortens what I'm typing, not changing the intent. – Matthew Scharley Oct 07 '09 at 05:43
17

Throwing NullReferenceException:

if (FooLicenceKeyHolder == null)
    throw new NullReferenceException();
leppie
  • 115,091
  • 17
  • 196
  • 297
  • 2
    Also, I think the general antipattern would be manually throwing *any* exception that the runtime itself throws when something bad happens – Matthew Scharley Oct 07 '09 at 05:46
  • Yes, but this one is particularly misleading because that is not really what happened. – Ed S. Oct 07 '09 at 06:15
  • 5
    I doubt that ArgumentNullException is the way to go in this case since from the code, it does not seem that this.FooLicenseHolder is an argument of a function (at least is does not LOOK like one conventions-wise). Perhaps rephrasing the code a bit would make your (perfectly valid) point little clearer. – petr k. Oct 07 '09 at 20:22
  • @petr: You are correct indeed. This is property, and not a parameter. Which makes the code even more horrible! – leppie Oct 08 '09 at 05:14
  • Hopefully we can start to get rid of this with Code Contacts in .Net 4.0 – Matthew Whited Oct 08 '09 at 13:19
  • @matthew: nothing stops you from writing your own little Contracts class :) – leppie Oct 08 '09 at 17:49
  • How about extension methods? Wouldn't there be a good place to use NullReferenceExceptions? – Andrei Rînea Oct 28 '10 at 18:58
16

This is true I seen it with my own eyes.

public object GetNull()
{
     return null;
}

It was actually used in the app, and even had a stored procedure to go with it too, an sp_GetNull that would return null....

that made my day.

I think the sp was used for a classic asp site .. something to do with a result set. the .net one was someone idea of "converting" the code into .net...

dmportella
  • 4,614
  • 1
  • 27
  • 44
14
int foo = 100;
int bar = int.Parse(foo.ToString());

Or the more general case:

object foo = 100;
int bar = int.Parse(foo.ToString());
leppie
  • 115,091
  • 17
  • 196
  • 297
  • 9
    This... what? Why? -headdesk- You can't possibly tell me that someone did this? – Matthew Scharley Oct 07 '09 at 05:25
  • I have actually refactored quite a lot of this out of our codebase O_o – Andrew Barrett Oct 07 '09 at 05:27
  • @matthew: added a more general case (aka from the datatable, hehe) – leppie Oct 07 '09 at 05:29
  • Yea, ok, I can see people doing it for an object. But for an `int` to an `int` assignment... – Matthew Scharley Oct 07 '09 at 05:30
  • 2
    I kid you not, I've seen people doing this for ints, one of many WTF moments I had. – Andrew Barrett Oct 07 '09 at 05:33
  • I've seen examples of that as well, although to be fair, there was quite a bit of code between them to make it not as obvious, but still as stupid. – Michael Stum Oct 07 '09 at 06:30
  • I have seen this in my coworker's code once while doing a code review. A real WTF... – Meta-Knight Oct 07 '09 at 20:21
  • I've seen this exact type of code in an application that was outsourced to India ... that app was full of WTFs like this, actually it had almost every anti-pattern in this thread ... – Pop Catalin Oct 08 '09 at 14:21
  • lol once I did string number = 1.ToString(); it was a Friday by the end of the day, so I don't blame him =P (yeah it sucked when I saw it the next Monday, I felt so embarrassed) – Carlo Oct 08 '09 at 16:01
  • @Carlo: that is really quite good practice; 1.ToString() will use the locale settings in case 1 is usually spelled something else by default :) (_Perhaps they'll get the UNICODE 'smart' version of the number, much like MS Word likes to give you their 'smart' quotes whenever you don't ask for them_) – sehe Jul 13 '11 at 19:17
  • @sehe hahaha nothing to be embarrassed about then! – Carlo Jul 14 '11 at 00:11
12

I have found this in our project and almost broke the chair...

DateTime date = new DateTime(DateTime.Today.Year, 
                             DateTime.Today.Month, 
                             DateTime.Today.Day);
leppie
  • 115,091
  • 17
  • 196
  • 297
Adriaan Stander
  • 162,879
  • 31
  • 289
  • 284
  • i think the general case anti pattern is just totally botching the use of the DateTime/TimeSpan classes. – anthony Oct 07 '09 at 05:35
  • 1
    I think that refusing to use or not knowing what Timespan objects are is a good one here too. – Spence Oct 07 '09 at 05:40
  • 7
    For the record, the correct usage is: DateTime date = DateTime.Now; – Wedge Oct 07 '09 at 05:40
  • 8
    or DateTime date = DateTime.ToDay; – Adriaan Stander Oct 07 '09 at 05:43
  • Wouldn't those (Now and ToDay) give date objects with hours and minutes etcetera, where the example just has the date part? – Svante Svenson Oct 07 '09 at 20:21
  • 12
    Actually, the correct usage is: DateTime date = DateTime.Now.Date; (or Today.Date) If you omit the Date you will get the time also. – Meta-Knight Oct 07 '09 at 20:26
  • 6
    And I don't really see a big problem with this code, maybe the coder just didn't know about the Date property... -1 – Meta-Knight Oct 07 '09 at 20:26
  • 3
    Um, Correct usage is Datetime date = `Datetime.Now.Date` – Spence Oct 07 '09 at 20:37
  • Right, you should always use the constructor with explicit DateTimeKind-information (local / UTC). – Simon D. Oct 07 '09 at 21:20
  • 2
    @astander, svinto: Really?? "ToDay"?? Are you serious? For crying out loud, camel casing is really starting to get out of hand! It's one freaking word. Today. – P Daddy Oct 08 '09 at 21:20
  • Seen worse: DateTime dt = new DateTime(2001, 1, 1, TimeSpan.FromSeconds(seconds).Hours, TimeSpan.FromSeconds(seconds).Minutes, TimeSpan.FromSeconds(seconds).Seconds); – GeReV Feb 03 '10 at 21:04
11

Quite often I stumble over this kind of var-abuse:

var ok = Bar();

or even better:

var i = AnyThing();

Using var that way makes no sense and gains nothing. It just makes the code harder to follow.

  • 8
    I agree - var seems to be getting very overused recently. – Paddy Oct 07 '09 at 20:39
  • 27
    I don't see an antipattern here, the var removes redundant type definition, as Bar() or AnyThing() will always return the same type. If you will ever change the return type of Bar() or AnyThing(), e.g. use an interface instead of the implementation, you will not need to change ok and i if they only require the interface, which is nice. – Simon D. Oct 07 '09 at 21:08
  • 11
    It's bad because you are not able to spot the type instantly without knowing the Bar() and AnyThing() methods. In my opinion Readability is more important than saving a few redundant characters. Apart from this, var is very usefull for statements like this: var i = new MyTypeWithVeryLongName(); The difference is that you can recognice the type instantly. – Christian Schwarz Oct 08 '09 at 06:28
  • is this C#? Doesn't compile at my side ;) – exhuma Oct 08 '09 at 07:22
  • 8
    var something = new Something() is fine. You know what type the object will be. Even better is when var is combined with generic methods to reduce duplication (follows DRY rule). – Finglas Oct 08 '09 at 08:35
  • I don't see a problem with this if 1. The method's name is clear and 2. The variable's name is clear. – Meta-Knight Oct 08 '09 at 13:11
  • 8
    Unfortunately ReSharper seems to enjoy suggesting any variable declaration should use var.. – Jess Oct 08 '09 at 13:32
  • 2
    It would be tolerable if you could hover over the variable and see its inferred type. – Juliet Oct 08 '09 at 14:15
  • @Dockers. You provide an example of "Don't Repeat Yourself", but those in the post are more like "Don't Say Anything". – Daniel Daranas Oct 08 '09 at 14:18
  • 2
    This would be OK if these were *constructors*, but they are not. It would be OK if these were factory classes too, if the type is obvious (e.g. `Service.Create(...)`) – Adam Luter Oct 08 '09 at 17:13
  • 3
    I don't see why this would be an anti-pattern in C# when it's apparently perfectly fine in type-inference languages (Haskell, F#, etc) and weakly-typed languages (JavaScript, Python, etc) or even the *only* way you can do it. – JulianR Oct 08 '09 at 20:38
  • 3
    I would reword it to be if it isn't clear what Something() returns. var person = FindPersonByAddress(address); is incredibly clear to me. – Matt Briggs Oct 09 '09 at 12:41
  • 1
    @Julian: Why do you think we're using C# and not PHP? They aren't anti-patterns in those languages specifically because they can't be, it's the only WTDI. In C#, there's more, and better, ways to do it. – Matthew Scharley Oct 21 '09 at 22:33
  • @Andrew Koester -- You can change that in ReSharper. You can make it always suggest the actual type instead of "var", or just make it shut up about it – Robert Fraser May 25 '10 at 10:29
10
anthony
  • 40,424
  • 5
  • 55
  • 128
  • Would be useful to split these into separate answers that can be voted up/down independently. – Bevan Oct 07 '09 at 06:08
  • 1
    public event EventHandler MyEvent = delegate { }; <-- no null check needed anymore. – Ed S. Oct 07 '09 at 06:21
  • Also, you can omit braces for the uppermost using blocks, so not too bad to have a few in there. – Ed S. Oct 07 '09 at 06:21
  • Resources can be multiply-specified in using blocks, which can eliminate the need for deep nesting. See http://www.levelofindirection.com/journal/2009/9/24/raii-and-readability-in-c.html – Robert Harvey Oct 08 '09 at 16:13
  • @Ed Swangren: The dummy delegate is bad for performance, and saves a minuscule amount of typing. It's better to do the null check. – P Daddy Oct 08 '09 at 21:43
  • 2
    @Ed Swangren: A call through a delegate is much more expensive than an `if` test, and if somebody *does* hook up to it, then it becomes a multicast delegate, which is much more expensive than a call through a unicast delegate. See the comments in response to this post: http://stackoverflow.com/questions/9033/hidden-features-of-c/9282#9282 – P Daddy Oct 09 '09 at 12:48
10

Not understanding that bool is a real type, not just a convention

if (myBooleanVariable == true)
{
    ...
}

or, even better

if (myBooleanVariable != false)
{
    ...
}

Constructs like these are often used by C and C++ developers where the idea of a boolean value was just a convention (0 == false, anything else is true); this is not necessary (or desirable) in C# or other languages that have real booleans.

Updated: Rephrased the last paragraph to improve its clarity.

Bevan
  • 43,618
  • 10
  • 81
  • 133
  • 3
    In C and C++ (I've not heard of the C/C++ language, yet), that is not a convention, and it's actually wrong. Since "everything else" is true, doing `if(a == true)`, for some definition of true (say, `1`), will not work as intended if `a` is, say, `4`. Likewise, in both cases, `if(myBooleanVar)` and `if(!myBooleanVar)` would be a better replacement. – Tordek Oct 07 '09 at 06:36
  • Great comment - good to go into detail. I'm curious though, based on your comments, why do so C++ developers who move to C# insist on always writing comparisons with true and false? (I've worked with several, and all of them have insisted on this practice, citing C++ as the reason). – Bevan Oct 07 '09 at 18:31
  • 1
    if (myBool == true) can make sense, if myBool is a nullable boolean. – Rauhotz Oct 07 '09 at 20:19
  • 1
    Is this really an anti-pattern or just a irritating redundancy? – Jeff Sternal Oct 07 '09 at 20:41
  • @JeffSternal - I think this an anti-pattern because (at least in the cases I've seen) it reflects a real lack of understanding about the C# type system. – Bevan Oct 07 '09 at 22:14
  • In Java, `Boolean a = null; boolean b = a == true;` NPEs, IIRC. Is C# different? – Tom Hawtin - tackline Oct 08 '09 at 03:21
  • Yes, C# is different, because there is only one type: Boolean, defined in the framework. C# has 'bool' but that's purely an alias for exactly the same thing. "Boxing" - the process of wrapping a value type to store it on the heap - has only an effect for performance, not for anything else. A nullable-bool is a different type again, see http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx for details. – Bevan Oct 08 '09 at 04:27
  • "In C and C++ (I've not heard of the C/C++ language, yet)". *and* is what the "/" character means in the sentence. Do you know a different definition than http://dictionary.reference.com/help/faq/language/g61.html#Slash ? – Greg Oct 08 '09 at 13:22
9

Public variables in classes (use a property instead).

Unless the class is a simple Data Transfer Object.

See comments below for discussion and clarification.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • 5
    The "Unless" above should trigger a warning bell - maybe this isn't so clear-cut after all? – d91-jal Oct 07 '09 at 08:24
  • 2
    Does it hurt for simple DTOs to use properties instead of public variables? I would say not anymore since auto-properties exist. But since I found out that WPF data bindings don't work with public fields (in contrast to public properties) made me forget about ever declaring public fields/variables without accessors again. – Simon D. Oct 07 '09 at 21:01
  • Just use properties. The JITer will try to inline them for you making them the same as the field instead of method calls. – Matthew Whited Oct 08 '09 at 13:13
  • The condition I would put on the "unless" is if the class does not and never will have any invariants it needs to enforce. – peterchen Oct 08 '09 at 13:19
  • Automatic properties makes the "Unless" pointless. Properties should be used for all public access to variables. – Darien Ford Oct 08 '09 at 14:34
  • I agree with the use of automatic properties exclusively, for those c# projects that support it. – Robert Harvey Oct 08 '09 at 15:51
  • I work with relatively old VB code that doesn't have automatic properties yet everyone I work with insists on declaring 10 fields as private and 10 getter/setter properties without any of the properties having custom processing. – Josh Smeaton Oct 09 '09 at 12:49
  • @Matthew Whited -- Nope, struct properties are NEVER inlined (in fact, any metod accepting or returning a struct is never inlined (unless the struct is a ref or out parameter)). Only reference and primitive type properties are inlined. Also, this may differ based on framework (i.e. compact, micro, Mono, etc.) – Robert Fraser May 25 '10 at 10:35
  • 1
    @Robert Frazer: .Net 3.5+ `Inlining of value types (C# structs). (X86)` http://blogs.msdn.com/b/vancem/archive/2008/05/12/what-s-coming-in-net-runtime-performance-in-version-v3-5-sp1.aspx – Matthew Whited May 25 '10 at 11:03
  • @Matthew Whited - My bad; didn't know they fixed that one! The bug is still open on Connect. That's awesome; I can be a lot less scared of structs now. – Robert Fraser May 27 '10 at 00:16
8

I have actually seen this.

bool isAvailable = CheckIfAvailable();
if (isAvailable.Equals(true))
{ 
   //Do Something
}

beats the isAvailable == true anti-pattern hands down!
Making this a super-anti-pattern!

Binoj Antony
  • 15,886
  • 25
  • 88
  • 96
  • Wow! Just Wow! I've seen string.Equals used before for strings instead of ==, but that was much more understandable - the guy in question didn't know the == operator was overloaded. But what you've shown takes the cake! – Phil Dec 22 '09 at 22:01
6
object variable;
variable.close(); //Old code, use IDisposable if available.
variable.Dispose(); //Same as close.  Avoid if possible use the using() { } pattern.
variable = null; //1. in release optimised away.  2. C# is GC so this doesn't do what was intended anyway.
Spence
  • 28,526
  • 15
  • 68
  • 103
  • 1
    @Spence: `.Close()` isn't necessarily 'old code'. Some classes provide a `Close()` method as an alias to `Dispose()` where close makes more sense semantically. – Matthew Scharley Oct 07 '09 at 05:28
  • True. But forcing IDisposable allows you to use static analysis tools to spot when types implementing IDisposable wasn't used. Additionally all APIs that microsoft had access to implemented IDisposable to allow for the using() pattern. Basically they standardised the pattern making it easier to spot mistakes. .Close() api's are usually throwbacks to the non .Net APIs that this code calls to. – Spence Oct 07 '09 at 05:31
  • Just to clarify, to spot when IDisposable objects were not disposed. – Spence Oct 07 '09 at 05:32
  • Just to add: Setting Disposed objects to null makes sense at least for WinForms controls to prevent a memory leak: http://social.msdn.microsoft.com/Forums/en-US/netfxcompact/thread/6d89a165-0d20-4002-823c-d5ece84f7518 – Michael Stum Oct 07 '09 at 06:36
  • 2
    You had me scared then. This is a bug in the .Net compact framework, not in win forms. Weak reference works in the real .net CLR and I also stand by the fact that the call to null will be optimised away in release mode (which was one of the main motivations for the dispose pattern, which is a method call forcing the lifetime of the object to last at least that long). But .Net CF is definately an interesting beast. – Spence Oct 07 '09 at 08:47
6

Private auto-implemented properties:

private Boolean MenuExtended { get; set; }
leppie
  • 115,091
  • 17
  • 196
  • 297
  • Is there soemthing wrong with this other than the fact you're introducing a method call into somewhere it's not likely to be needed? – Matthew Scharley Oct 07 '09 at 05:37
  • @matthew: I cannot think of a single reason/case when a field would not be better. – leppie Oct 07 '09 at 05:41
  • 7
    Auto-implemented property might be converted later into a full-blown property with custom getter and setter methods.. You can't easily do this to a field. – Gart Oct 07 '09 at 05:49
  • 5
    You can, but not in a binary compatible way... but then again, they are private anyway, so they will be binary compatible since the field/property isn't exposed. – Matthew Scharley Oct 07 '09 at 05:51
  • 1
    I don't see a problem with this, and I think it can often be a worthwhile design choice. Though, of course, it can be abused. – Wedge Oct 07 '09 at 05:54
  • 3
    For one, some controls only reflect properties, not fields. The PropertyGrid for example. Sometimes you need to use properties when dealing with reflection, even if those properties are private. – rein Oct 07 '09 at 06:09
  • @leppie: It involves some code refactoring and may be a problem if this field is used in many places.. Visual studio's automatic refactoring helps here but not in every case. – Gart Oct 07 '09 at 06:17
  • As Matthew said above, the reason you'd have placeholder/empty auto properties is for binary compatibility. A private property has no future binary compatibility requirements. – vanja. Oct 07 '09 at 06:19
  • 1
    This is wrong. Data binding only works on properties (not fields). – Ed S. Oct 07 '09 at 06:27
  • 3
    @ed: Good luck binding to a private property! – leppie Oct 07 '09 at 07:08
  • 5
    Binary compatibility and data-binding are reasons you might need to use public properties, but those don't apply here. There are several advantages to properties. You can put a debug breakpoint on access. You can easily change their read/write access level. And they can often be useful in refactoring, migrate null checks paired with default values into the property itself, for example. Given the tiny difference in effort needed to create auto-implemented properties, I'd say it's a wash whether properties or fields are the better default. – Wedge Oct 07 '09 at 10:07
  • 1
    I personally prefer defaulting to private properties than figuring out, every time I create a field, whether or not I'm ever going to want it to be visible to reflection. The rationalization for making them fields (eliminating unnecessary getter/setter method calls) smells like premature optimization to me. – Robert Rossney Oct 07 '09 at 18:04
  • 1
    @robert; why would a field not be visible via reflection? – leppie Oct 07 '09 at 19:29
  • 1
    I suppose there could be some hard found justifications for doing this, but I'd say it passes the litmus test as an anti-pattern. – Greg Oct 08 '09 at 13:29
  • 1
    I sure wish I knew what I was talking about. – Robert Rossney Oct 08 '09 at 16:25
6

Declaring and initializing all local variables at the top of each method is so ugly!

void Foo()
{
    string message;
    int i, j, x, y;
    DateTime date;

    // Code
}
  • 3
    That's how I was taught to code in college ;) Don't do it anymore though, it's a pain. – Ed James Oct 08 '09 at 14:03
  • This made sense way back before IDEs. – Dean J Oct 08 '09 at 14:18
  • 12
    Isn't this more of a subjective opinion than a C# anti pattern? – Patrik Svensson Oct 08 '09 at 15:56
  • 3
    What's wrong with this? If you're coding your methods properly, they're short enough to see all your variables anyways. I would submit that the variables should be defined at the top of their block, rather than method, unless they must be for scope issues. – snicker Oct 08 '09 at 21:42
  • I'd agree with this - even if you keep your functions fairly small, if a variable is only used for a few lines you can often immediately see the type without your eyes having to seek up to the top of the function. Initializing at the top to me, shows either lack of experience, or over reluctance to break old habits. – Phil Dec 22 '09 at 21:56
  • 1
    It basically trickles from C programming in my opinion because you need to declare all variable before any function call. – K Singh Jan 22 '10 at 07:48
  • where else u supposed to define, this requires u to pre think about ur method. – DarthVader Aug 25 '11 at 17:32
6

Two string anti patterns
Anti-Pattern # 1
Checking strings for null or empty

//Bad
if( myString == null || myString == "" )
OR
if( myString == null || myString.Length == 0 )

//Good
string.IsNullOrEmpty(myString)

Anti-Pattern # 2 (only for .NET 4.0)
Checking strings for null or empty or white space

//Bad
if( myString == null || myString == "" || myString.Trim() == "")

//Good
string.IsNullOrWhiteSpace(myString) 
Binoj Antony
  • 15,886
  • 25
  • 88
  • 96
5

Needless casting (please trust the compiler):

foreach (UserControl view in workspace.SmartParts)
{
  UserControl userControl = (UserControl)view;
  views.Add(userControl);
}
leppie
  • 115,091
  • 17
  • 196
  • 297
5
if(data != null)
{
  variable = data;
}
else
{
  variable = new Data();
}

can be better written as

variable = (data != null) ? data : new Data();

and even better written as

variable = data ?? new Data();

Last code listing works in .NET 2.0 and above

Binoj Antony
  • 15,886
  • 25
  • 88
  • 96
4

Speaking with an accent always caught me.

C++ programmers:

if (1 == variable) { }

In C# this will give you a compiler error if you were to type if (1 = variable), allowing you to write the code the way you mean it instead of worrying about shooting yourself in the foot.

Spence
  • 28,526
  • 15
  • 68
  • 103
  • I wouldn't generalize that to C++ programmers...sure, the ones that do it are probably from C or C++, but most programmers think it's annoying to read and don't do it. – GManNickG Oct 07 '09 at 05:39
  • 2
    and yet is the safe thing to do. If you make a typo (= instead of ==) you end up with "1 = variable" and the compiler will call you up on it. – vanja. Oct 07 '09 at 06:24
  • `int variable = 5; if (1 == variable) { }` doesn't give me any error. – Joren Oct 07 '09 at 06:36
  • 8
    C# makes this convention unnecessary. This code: Int32 x = 5; if (x = 5) { } results in Error 74: Cannot implicitly convert type 'int' to 'bool' Changing "=" to "==" works fine. – JeffK Oct 07 '09 at 21:12
  • Except if the variable is of boolean type? – Tom Hawtin - tackline Oct 08 '09 at 03:15
  • @Tom Hawtin wow. It's a warning at least. It won't work for anything except boolean types, but still, WHY. *Why* in gods name would you want the assignment operator to return the value assigned. You have this variable thing that should have your value in it now... – Spence Oct 08 '09 at 04:11
  • 2
    @spence making = return the assigned value allows for the pattern: while((line=r.ReadLine()) != null){//do stuff to line} – Esben Skov Pedersen Oct 09 '09 at 13:30
  • I see this in our code, one developer uses it to much chagrin of the development manager. You get a compile error if you put a single equals, so why write it this way? – Paul Talbot Jun 02 '10 at 09:00
4

Not using ternary's is something I see converts to c# do occasionally

you see:

private string foo = string.Empty;
if(someCondition)
  foo = "fapfapfap";
else
  foo = "squishsquishsquish";

instead of:

private string foo  = someCondition ? "fapfapfap" : "squishsquishsquish";
IanStallings
  • 806
  • 10
  • 21
  • I was one of the converts and did this a few times - thank got for Resharper saving my ass :) +1 – Andrew Oct 08 '09 at 20:46
  • 7
    I've met quite a few people who were **adamantly** opposed to *EVER* using ternary conditionals, saying that it makes for "unreadable code". Fools. – snicker Oct 08 '09 at 21:51
  • 2
    I am as well cautious about ternary statements. Sometimes I prefer them sometimes not. Is there a good reason (language-wise) to *always* use them in C#? – exhuma Oct 09 '09 at 08:15
  • @exhuma: You shouldn't *always* use anything, but `?:` *can* make the intent of the code clearer. An 'if`/`else` block not only takes up more space (making your eyes scan several lines to determine intent), but also makes the decision logic the primary focus, whereas the ternary operator allows the assignment (or argument selection) to be the primary focus. I find this less distracting. Personally, I only use it when it fits comfortably on one line. Exception: combined ternary operations, properly formatted on several, can sometimes be more readable than multiple `if`s, or even a `switch`. – P Daddy Oct 09 '09 at 12:34
  • 2
    If there is only one "thing" in each of the conditionals, then the ternary operator is great. But calling functions (especially with multiple parameters), concatenating strings, etc makes for bad readability. – DisgruntledGoat Oct 12 '09 at 18:55
  • It would be nice to include `{}` brackets after condition, even if it's one-line code. – Dariusz Woźniak Aug 11 '10 at 09:33
3

Accessing modified closures

foreach (string list in lists)
{
        Button btn = new Button();
        btn.Click += new EventHandler(delegate { MessageBox.Show(list); });
}

(see link for explanation and fix)

Community
  • 1
  • 1
Greg
  • 16,540
  • 9
  • 51
  • 97
3

For concating arbitrary number of strings using string concatenation instead of string builder

Exampls

foreach (string anItem in list)
    message = message + anItem;
Kaz
  • 181
  • 2
  • 12
2

is this considered general ?

public static main(string [] args)
{
  quit = false;
  do
  {
  try
  {
      // application runs here .. 
      quit = true;
  }catch { }
  }while(quit == false);
}

I dont know how to explain it, but its like someone catching an exception and retrying the code over and over hoping it works later. Like if a IOException occurs, they just try over and over until it works..

Andrew Keith
  • 7,515
  • 1
  • 25
  • 41
  • 1
    This is probably a literal translation of VB6 "On Error Resume Next" – Benjol Oct 07 '09 at 05:36
  • There are sometimes valid reasons for this pattern, but it usually indicates a design flaw. – Wedge Oct 07 '09 at 05:41
  • 1
    Not quite, a literal translation of that 'pragma'(?) would be a try/catch around every line and silently throwing away `Exception`. – Matthew Scharley Oct 07 '09 at 05:45
  • 1
    In some cases, for example, network connections, if you get disconnected you may want to auto-reconnect. This requires catching the i/o exceptions, then starting your loop over again. Maybe your internet connection went down, which means it will try again and again until it's back up. This is more common in sevices IMO. – Erik Funkenbusch Oct 08 '09 at 05:49
  • It's perfectly valid, if you want an infinite wait instead of a clear exception message in case of bug. – Daniel Daranas Oct 08 '09 at 14:25
  • This is *almost* how I implemented a menu system the first time I played with Java in my first year of uni. I've come a bit of a way since then. – Josh Smeaton Oct 09 '09 at 12:56
2

The project I'm on had fifty classes, all inheriting from the same class, that all defined:

public void FormatZipCode(String zipCode) { ... }

Either put it in the parent class, or a utility class off to the side. Argh.

Have you considered browsing through The Daily WTF?

Dean J
  • 39,360
  • 16
  • 67
  • 93
1

Massively over-complicated 'Page_Load' methods, which want to do everything.

Ralph Lavelle
  • 5,718
  • 4
  • 36
  • 46
1

Using properties for anything other than to simply retrieve a value or possibly an inexpensive calculation. If you are accessing a database from your property, you should change it to a method call. Developers expect that method calls might be costly, they don't expect this from properties.

triskelion
  • 186
  • 2
  • 6
  • 1
    I don't think developers (especially new ones) *intuitively* expect that properties should be fast. I think they expect it *if they've been told to expect it*. Maybe that's just me though. – Greg Oct 08 '09 at 13:58
  • @Greg: I disagree. A property *looks like* a variable access (especially to new developers). `int a = foo.Metric;` *looks* fast. – P Daddy Oct 08 '09 at 20:58
  • 1
    I don't agree and the LINQ-TO-SQL framework doesn't either since it exposes an entire database through properties – Esben Skov Pedersen Oct 09 '09 at 13:31
1

Found this a few times in a system I inherited...

if(condition){
  some=code;
}
else
{
  //do nothing
}

and vice versa

if(condition){
  //do nothing
}
else
{
  some=code;
}
Andrew
  • 9,967
  • 10
  • 64
  • 103
  • I have accidentally done this when I wanted to return to that block and put in the other clause BUT I now mark it with //TODO: so I can find that tag. I've never just left that blank intentionally, that seems to be a case of being "out in space" while working. – IanStallings Oct 08 '09 at 21:00
  • but i've seen it commented implying nothing is required and it made me giggle at the time :) – Andrew Oct 08 '09 at 21:12
  • Those are the best. Right up there with empty catch blocks. – IanStallings Oct 08 '09 at 21:40
  • 5
    It shows clearly that the author thought about the case when the expression evaluates to one of the values and actively decided that there's nothing to do. I think this actually helps readability if used correctly. – erikkallen Oct 10 '09 at 12:13
1

I've had this one before:

AnEnum e = AnEnum.Abc;
int i = (int)e;
// lots of code
AnEnum f = (AnEnum)Enum.Parse(i, typeof(AnEnum));
Darko
  • 38,310
  • 15
  • 80
  • 107
1
if (state == ((int)RowState.Active).ToString())
else if (state == ((int)RowState.NotActive).ToString())

state is a string post value that contain a value from the enum RowState.

Ultimately this is the way we use to check against the value.

Fitzchak Yitzchaki
  • 9,095
  • 12
  • 56
  • 96
1

The main issue with .NET seems to be the fact that there are many developers coming from VB 6.0 or (even worse in my opinion, because they mistakenly BELIEVE that they know what to do while VB 6.0 programmers are at least humble enough to be willing to learn something new) Java / C++.

People too ignorant towards modern paradigms, people plastering their code with ugly P/Invoke in the worst C++ - style possible. :-(

  • 1
    I agree to some degree. But the problem is not always the *willingness* to learn. My case is similar, due to a corporate decision I have to code in C# now. And a quick 5-day crash-course is supposed to be enough. I don't believe it is. And I am convinced that I will write bad code at first. Which is why I opened this question. To avoid at least *some* bad code :) – exhuma Jun 02 '10 at 08:53
  • exhuma, a 5 day course is NOT enough, sadly. At least C# is not a hard language to learn, but there are a few things you shouldn't do and there are a lot of best practices. I have, however, seen total garbage code like manually iterating instead of using foreach(...) and all that. Mostly it's because people come from a clumsy language like VB, C++ or Java. Just think about it this way: C# is the least clumsy language available. If something feels clumsy, it's not coded correctly. – stormianrootsolver Jun 02 '10 at 09:27
  • Which is exactly what I meant... :) You can say this with many languages. One needs experience! – exhuma Jun 03 '10 at 06:50
0

Ignorance is bliss (know your framework):

TimeSpan keyDays = new TimeSpan(Licence.LicenceExpiryDate.Ticks);
TimeSpan nowDays = new TimeSpan(System.DateTime.Now.Ticks);

int daysLeft = keyDays.Days - nowDays.Days;
leppie
  • 115,091
  • 17
  • 196
  • 297
  • 3
    Sure, this is rather verbose and partly redundant. Could have been int daysLeft = DateTime.Now.Subtract(Licence.LicenceExpiryDate).Days; But verbosity IMHO is not antipattern, performance and readability should not suffer too much, here. – Simon D. Oct 07 '09 at 21:37
  • 4
    Stupidity is an anti-pattern :) – leppie Oct 08 '09 at 05:12
  • @exhuma: you can do the same with: (Licence.LicenceExpiryDate - DateTime.Now).Days – leppie Oct 09 '09 at 09:58
  • Without looking up in the IDE, shouldn't that be TotalDays leppie? – Phil Dec 22 '09 at 22:02
  • Ah, oops - my bad. So, TotalDays gives fractional days while Days just provides whole days. – Phil Dec 22 '09 at 22:04
  • Hmmm, actually come to think of it, that makes your suggestion produce different values Leppie - subtracting one from the other will produce a different timespan than keyDays.Days - nowDays.Days since the latter produces a timespan delta from the beginning of the day for keyDays.Days and nowDays.Days. Assuming that's what they actually want you'd have to use: (License.LicenseExpiryDate.Date - DateTime.Now.Date) – Phil Dec 22 '09 at 22:09
  • @Phil: I didn't even notice that. For this code I think it was purely displaying number of days left on license. – leppie Dec 23 '09 at 05:36
0

When coding a property, just automatically giving it a getter and setter without thinking about its use. Often the get or set is not used and the property should be read (get) only or write (set) only.

bytedev
  • 8,252
  • 4
  • 48
  • 56
0

I just saw a few lately.

Never Ending Param Chain

public string CreateJob(string siteNumber, string customer, string jobType, string description, string reference, string externalDoc, string enteredBy, DateTime enteredDateTime)
    {
        //recordtype = 0 for job
        //load assignments and phases set to false
        return Create(0, siteNumber, customer, jobType, description, reference, externalDoc, enteredBy, enteredDateTime, false, false);
    }

public string Create(int recordType, string siteNumber, string customer, string jobType, string description, string reference, string externalDoc, string enteredBy, DateTime enteredDateTime, bool loadAssignments, bool loadPhases)
{
    _vmdh.Fields.FieldByName("WDDOCTYPE").SetValue(recordType, false);
    _vmdh.Fields.FieldByName("NMDOCID").SetValue(-1, false);
    _vmdh.Init();           
        ....
        ...
        // And it keeps going
    }

Wonder what happens at form close

 private void frmAddImages_FormClosing(object sender, FormClosingEventArgs e)
{
    if (DialogResult != DialogResult.OK)
    {
        if (IsDirty)
        {
            e.Cancel = !(MessageBox.Show("Are you sure that you want to exit without saving", "Form Not Saved", MessageBoxButtons.YesNo) == DialogResult.Yes);
        }
    }
    }

Stringly Typed

switch (cbDateFilter.Text)
            {
                case "This Week":
                    dt = DateTime.Now;
                    while (dt.DayOfWeek != DayOfWeek.Monday) dt = dt.AddDays(-1); //find first day of week
                    dtFrom.Value = DateTime.Parse(dt.ToString("dd/MM/yyyy 00:00:00"));
                    dtTo.Value = DateTime.Parse(dt.AddDays(6).ToString("dd/MM/yyyy 23:59:59"));
                    break;

                case "This Month":
                    dt = DateTime.Now;
                    while (dt.Day != 1) dt = dt.AddDays(-1); // find first day of month
                    dtFrom.Value = DateTime.Parse(dt.ToString("dd/MM/yyyy 00:00:00"));
                    dtTo.Value = DateTime.Parse(dt.AddMonths(1).AddDays(-1).ToString("dd/MM/yyyy 23:59:59"));
                    break;

                case "This Quarter":
                    // if at end of Quarter then we need subtract -4 to get to priv Quarter
                    dt = DateTime.Now;
                    while (dt.Month != 7 &&
                        dt.Month != 10 &&
                        dt.Month != 1 &&
                        dt.Month != 4) dt = dt.AddMonths(-1); //find first month, fiscal year
                    while (dt.Day != 1) dt = dt.AddDays(-1); // find first day on month
                    dtFrom.Value = DateTime.Parse(dt.ToString("dd/MM/yyyy 00:00:00"));
                    dtTo.Value = DateTime.Parse(dt.AddMonths(3).AddDays(-1).ToString("dd/MM/yyyy 23:59:59"));
                    break;
Raghu
  • 2,678
  • 2
  • 31
  • 38
0

Using (bad)

IEnumerable<Bar> foo = ...
if (foo.Count() > 0)
{
    ...
}

instead of (good)

IEnumerable<Bar> foo = ...
if (foo.Any())
{
    ...
}

to test whether an IEnumerable contains anything. Count() has to enumerate through the entire collection with MoveNext(), while Any() only has to call MoveNext() once.

Mark Nelson
  • 151
  • 4
-2

Overuse/abuse of object initializers for everything, probably because of laziness:

var person = new Person
{
    FirstName = "joe",
    (... lots of setters down here)
};

without realizing that this is almost as bad as making all the fields public. You should always take care into creating some valid constructors, that initialize your objects to a valid state.

mookid8000
  • 18,258
  • 2
  • 39
  • 63
  • 5
    IMHO, it's not a good design to create constructors with many parameters just to initialize your class. You should provide simple constructors and additional properties. Constructors (also applies to methods) with more than 3 parameters have a really bad smell. – Christian Schwarz Oct 07 '09 at 06:22
  • Unnecessarily writable (i.e., non-readonly) fields have a worse smell, IMO. – Tordek Oct 07 '09 at 06:40
  • 1
    I agree with both of your comments, but @Christian: if those are the required things to set for the object to be in a valid state, then IMO you _should_ make a ctor that requires all of them. Of course, there may be overloads accepting fewer parameters, that initialize the object with some sensible defaults via the `: this(...)` syntax. And yes, if the ctor takes more than 3 arguments I agree with you that it's starting to smell – mookid8000 Oct 07 '09 at 13:20
  • 1
    This code is much more readable than if it was turned into a constructor. – Egor Pavlikhin Oct 08 '09 at 16:05
  • @HeavyWave I agree with that when you're dealing with DTOs where null is an acceptable value for any of the classes properties, but it totally defeats the class' ability to guarantee any that it is valid or consistent – mookid8000 Oct 10 '09 at 08:19
  • @Christian: If you use immutability extensively, you might end up with 10-param constructors. Is immutability a smell? Or is a data object with 10 read-only properties a smell? I'd say neither Perhaps the smell is that there is no way to create a property that can only be set in a constructor or initializer block. – erikkallen Oct 10 '09 at 12:12