views:

2947

answers:

35
+44  Q: 

C# Antipatterns

Possible Duplicate:
Common programming mistakes for .NET developers to avoid?

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.
+9  A: 

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
The "Unless" above should trigger a warning bell - maybe this isn't so clear-cut after all?
d91-jal
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.
Simpzon
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
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
Automatic properties makes the "Unless" pointless. Properties should be used for all public access to variables.
Darien Ford
I agree with the use of automatic properties exclusively, for those c# projects that support it.
Robert Harvey
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
@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
@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
@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
+13  A: 
int foo = 100;
int bar = int.Parse(foo.ToString());

Or the more general case:

object foo = 100;
int bar = int.Parse(foo.ToString());
leppie
This... what? Why? -headdesk- You can't possibly tell me that someone did this?
Matthew Scharley
I have actually refactored quite a lot of this out of our codebase O_o
Andrew Barrett
@matthew: added a more general case (aka from the datatable, hehe)
leppie
Yea, ok, I can see people doing it for an object. But for an `int` to an `int` assignment...
Matthew Scharley
I kid you not, I've seen people doing this for ints, one of many WTF moments I had.
Andrew Barrett
You're right, they really should be using TryParse(). :P
rein
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
I have seen this in my coworker's code once while doing a code review. A real WTF...
Meta-Knight
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
I've actually seen a person do this. Horrible...
Patrik
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
Stumbled across this beauty last week, really makes me wonder...
wsanville
+2  A: 

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
This is probably a literal translation of VB6 "On Error Resume Next"
Benjol
There are sometimes valid reasons for this pattern, but it usually indicates a design flaw.
Wedge
Not quite, a literal translation of that 'pragma'(?) would be a try/catch around every line and silently throwing away `Exception`.
Matthew Scharley
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.
Mystere Man
It's perfectly valid, if you want an infinite wait instead of a clear exception message in case of bug.
Daniel Daranas
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
+1  A: 

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

Rafe Lavelle
C# has page load? Maybe you meant ASP?
Devtron
protected void Page_Load(object sender, EventArgs e) { // do stuff}
Rafe Lavelle
Devtron, C# is also a language of ASP.NET, which has a page load method
CRice
Yes but it's not an antipattern of the language (C#) it's an antipattern of ASP.NET...
Meta-Knight
Yep, that's true alright
Rafe Lavelle
+6  A: 
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
@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
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
Just to clarify, to spot when IDisposable objects were not disposed.
Spence
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
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
+38  A: 

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

Andrew Keith
And failing to wait for pending finalizers to complete, in the rare situations where you do want to force a collection.
Eric Lippert
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
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
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();'
Simpzon
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
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
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
@Pop Catalin -- All valid use cases... What exactly is a "normal application"? All those seem like prett "normal" applications to me.
Robert Fraser
@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
+12  A: 

Insulting the law of Demeter:

a.PropertyA.PropertyC.PropertyB.PropertyE.PropertyA = 
     b.PropertyC.PropertyE.PropertyA;
leppie
+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
@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
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
+52  A: 

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
True, dont ever hide the stack trace...
astander
`catch (Exception ex)` is an anti-pattern in itself.
Joren
Unless you're doing some logging or similar and then re-throwing it
thecoop
@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
catch (Exception ex) is perfectly valid for web applications. might be other cases too.
HeavyWave
aaah throw new Exception("There was an error", ex); so it shows the original exception as the inner exception, nice!
Carlo
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
+6  A: 

Private auto-implemented properties:

private Boolean MenuExtended { get; set; }
leppie
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
@matthew: I cannot think of a single reason/case when a field would not be better.
leppie
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
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
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
@gart: and how does that make any difference? Just convert field to property...
leppie
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
@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
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.
This is wrong. Data binding only works on properties (not fields).
Ed Swangren
@ed: Good luck binding to a private property!
leppie
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
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
@robert; why would a field not be visible via reflection?
leppie
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
I sure wish I knew what I was talking about.
Robert Rossney
+9  A: 
anthony
+1 for deep nesting.
rein
Would be useful to split these into separate answers that can be voted up/down independently.
Bevan
public event EventHandler MyEvent = delegate { }; <-- no null check needed anymore.
Ed Swangren
Also, you can omit braces for the uppermost using blocks, so not too bad to have a few in there.
Ed Swangren
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
@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
@P Daddy: Bad for performance how exactly?
Ed Swangren
@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
+10  A: 

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);
astander
i think the general case anti pattern is just totally botching the use of the DateTime/TimeSpan classes.
anthony
I think that refusing to use or not knowing what Timespan objects are is a good one here too.
Spence
For the record, the correct usage is: DateTime date = DateTime.Now;
Wedge
or DateTime date = DateTime.ToDay;
astander
Wouldn't those (Now and ToDay) give date objects with hours and minutes etcetera, where the example just has the date part?
svinto
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
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
Um, Correct usage is Datetime date = `Datetime.Now.Date`
Spence
Right, you should always use the constructor with explicit DateTimeKind-information (local / UTC).
Simpzon
@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
@Spence: No, correct is `DateTime.Today`.
P Daddy
Seen worse: DateTime dt = new DateTime(2001, 1, 1, TimeSpan.FromSeconds(seconds).Hours, TimeSpan.FromSeconds(seconds).Minutes,TimeSpan.FromSeconds(seconds).Seconds);
GeReV
+4  A: 

Needless casting (please trust the compiler):

foreach (UserControl view in workspace.SmartParts)
{
  UserControl userControl = (UserControl)view;
  views.Add(userControl);
}
leppie
What the crap is going on there? You get a UserControl , assign a new reference to it with a needless cast and then add it to itself? Why?
Ed Swangren
@ed: I wish I knew why, but found lurking some time ago in our codebase :)
leppie
@ed: it's not added to itself. `views` != `view`. ;)
exhuma
I guess Resharper would see what you did there.
comichael
+16  A: 

Throwing NullReferenceException:

if (FooLicenceKeyHolder == null)
    throw new NullReferenceException();
leppie
`ArgumentNullException` ?
Matthew Scharley
Yes, that would be the correct one to throw :)
leppie
Also, I think the general antipattern would be manually throwing *any* exception that the runtime itself throws when something bad happens
Matthew Scharley
Yes, but this one is particularly misleading because that is not really what happened.
Ed Swangren
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.
@petr: You are correct indeed. This is property, and not a parameter. Which makes the code even more horrible!
leppie
Hopefully we can start to get rid of this with Code Contacts in .Net 4.0
Matthew Whited
@matthew: nothing stops you from writing your own little Contracts class :)
leppie
How about extension methods? Wouldn't there be a good place to use NullReferenceExceptions?
Andrei Rinea
+4  A: 

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
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.
GMan
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.
`int variable = 5; if (1 == variable) { }` doesn't give me any error.
Joren
sorry, updated it now.
Spence
The safe thing to do is learn to program and type ==, not reverse things...
GMan
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
Except if the variable is of boolean type?
Tom Hawtin - tackline
@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
@spence making = return the assigned value allows for the pattern: while((line=r.ReadLine()) != null){//do stuff to line}
Esben Skov Pedersen
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?
Sres
+1  A: 

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
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.
Simpzon
Stupidity is an anti-pattern :)
leppie
so why is this "stupid"?
exhuma
@exhuma: you can do the same with: (Licence.LicenceExpiryDate - DateTime.Now).Days
leppie
Without looking up in the IDE, shouldn't that be TotalDays leppie?
Phil
Ah, oops - my bad. So, TotalDays gives fractional days while Days just provides whole days.
Phil
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
@Phil: I didn't even notice that. For this code I think it was purely displaying number of days left on license.
leppie
+29  A: 

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
Without the bonus it's not that painful (only the "== true")
ripper234
if (someCondition) return true; else return false; AAAARRRGGGG!!!!
Ed Swangren
With the first case, consider the case of something = false and somethingelse = true. You shouldn't refactor to somethingelse = something
vanja.
I agree with rupper234. It could actually improve readability in some cases.
HeavyWave
@vanya: Of course not. That's `somethingelse |= something`.
Tordek
We can make this better: if (something == true) { somethingelse = true; } else { somethingelse = false; } return somethingelse;
Wedge
other than this being verbose it is not a 'bug' as such.
John Nolan
saw this today on The Daily WTF http://thedailywtf.com/Articles/The-Clever-Coder.aspx
sstewart
@Tordek -- I've NEVER seen that construct used. I'd argue the if-statement version is more readable.
Robert Fraser
-1. It's more verbose than necessary, but beside that, there is nothing wrong with it.
Joh
@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
A: 

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
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
Unnecessarily writable (i.e., non-readonly) fields have a worse smell, IMO.
Tordek
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
This code is much more readable than if it was turned into a constructor.
HeavyWave
@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
@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
+9  A: 

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
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
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
if (myBool == true) can make sense, if myBool is a nullable boolean.
Rauhotz
Is this really an anti-pattern or just a irritating redundancy?
Jeff Sternal
@Rauhotz - good point, an edge case I hadn't thought of.
Bevan
@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
In Java, `Boolean a = null; boolean b = a == true;` NPEs, IIRC. Is C# different?
Tom Hawtin - tackline
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
"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
C++ does have booleans.
Daniel Daranas
+6  A: 

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
}
Christian Schwarz
That's how I was taught to code in college ;)Don't do it anymore though, it's a pain.
Ed Woodcock
This made sense way back before IDEs.
Dean J
Isn't this more of a subjective opinion than a C# anti pattern?
Patrik
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
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
It basically trickles from C programming in my opinion because you need to declare all variable before any function call.
Kavitesh Singh
+10  A: 

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.

Christian Schwarz
I agree - var seems to be getting very overused recently.
Paddy
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.
Simpzon
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
is this C#? Doesn't compile at my side ;)
exhuma
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
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
Unfortunately ReSharper seems to enjoy suggesting any variable declaration should use var..
Andrew Koester
It would be tolerable if you could hover over the variable and see its inferred type.
Juliet
@Dockers. You provide an example of "Don't Repeat Yourself", but those in the post are more like "Don't Say Anything".
Daniel Daranas
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
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
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
@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
@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
+13  A: 

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
maybe the coder assumed that null was a private variable ;O)
Simpzon
Well, you encapsulate the concept of nullity inside a function :P
Daniel Daranas
They must have thought null might change in the future :)
PeteT
+1  A: 

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
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
@Greg: I disagree. A property *looks like* a variable access (especially to new developers). `int a = foo.Metric;` *looks* fast.
P Daddy
I don't agree and the LINQ-TO-SQL framework doesn't either since it exposes an entire database through properties
Esben Skov Pedersen
+19  A: 

I see following code a lot:

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

should be:

       return (i==3);
Benny
Oh man I see that a lot... +1.
KG
Yeah I see that all the time. I always refactor it if I have the time.
rein
What's really bad here is the lack of parentheses :)
HeavyWave
The lack of parentheses? You must be referring to a styling preference.
Robert Harvey
Or at least drop the else, but I prefer the "should be" as you mention Benny.
Adam Luter
`return` is **not** a function. The parentheses are unnecessary.
P Daddy
ha, i see this answer a lot
dotjoe
@PDaddy: that is true, but the parentheses aid readability.
DisgruntledGoat
@DisgruntledGoat: They look like noise to me.
P Daddy
Playing devil's advocate - surely both will become exactly the same when compiled, so no speed difference, and the first version potentially more readable for more junior programmers?
Kris C
+3  A: 

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)

Greg
+2  A: 

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
Actually, The Daily WTF is one of my favourite reads ;)
exhuma
+3  A: 

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

Exampls

foreach (string anItem in list)
    message = message + anItem;
Kaz
Or at least use String.Join here.
Adam Luter
the perf gain often isn't worth the effort of StringBuilder
Scott Weinstein
This looks like a job for `string.Concat()`.
P Daddy
+4  A: 

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";
Ian S
I was one of the converts and did this a few times - thank got for Resharper saving my ass :) +1
Andi
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
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
@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
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
It would be nice to include `{}` brackets after condition, even if it's one-line code.
ventr1s
+1  A: 

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;
}
Andi
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.
Ian S
//TODO: is brilliant :)
Andi
but i've seen it commented implying nothing is required and it made me giggle at the time :)
Andi
Those are the best. Right up there with empty catch blocks.
Ian S
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
+17  A: 
using Microsoft.SharePoint;

'nuff said

Rubens Farias
I like this one :)
Ladislav Mrnka
+4  A: 
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
Err...I think your first example should be (data != null) or reverse the if / else part of the ternary block.
Chris Shouts
good catch, correcting...
Binoj Antony
I like this one, thanks
Sres
+8  A: 

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
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
A: 

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 Z
A: 
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.

Mendy
So, what would be the "correct" way of doing it then? This seems sensible to me. But then again, I don't know C# Enums... ;)
exhuma
It is the correct way, but the pattern here is definitely anti pattern :)
Mendy
A: 

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. :-(

stormianrootsolver
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
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
@stormian Which is exactly what I meant... :) You can say this with many languages. One needs experience!
exhuma
+3  A: 

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