C# Antipatterns

China☆狼群 提交于 2019-11-27 08:55:29

问题


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.

回答1:


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
}



回答2:


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




回答3:


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;
}



回答4:


using Microsoft.SharePoint;

'nuff said




回答5:


I see following code a lot:

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

should be:

       return (i==3);



回答6:


Insulting the law of Demeter:

a.PropertyA.PropertyC.PropertyB.PropertyE.PropertyA = 
     b.PropertyC.PropertyE.PropertyA;



回答7:


Throwing NullReferenceException:

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



回答8:


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




回答9:


int foo = 100;
int bar = int.Parse(foo.ToString());

Or the more general case:

object foo = 100;
int bar = int.Parse(foo.ToString());



回答10:


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);



回答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.




回答12:


  • Lack of null test before delegate invocation.
  • Not knowing when and how to use 'as' with a null check vs. a cast with a try/catch.
  • 'throw exception' vs. 'throw' within a catch block.
  • Instantiating a large number of strings instead of using StringBuilder.
  • Deep nesting of using blocks.



回答13:


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.




回答14:


Public variables in classes (use a property instead).

Unless the class is a simple Data Transfer Object.

See comments below for discussion and clarification.




回答15:


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!




回答16:


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.



回答17:


Private auto-implemented properties:

private Boolean MenuExtended { get; set; }



回答18:


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
}



回答19:


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) 



回答20:


Needless casting (please trust the compiler):

foreach (UserControl view in workspace.SmartParts)
{
  UserControl userControl = (UserControl)view;
  views.Add(userControl);
}



回答21:


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




回答22:


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.




回答23:


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";



回答24:


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)




回答25:


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

Exampls

foreach (string anItem in list)
    message = message + anItem;



回答26:


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




回答27:


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?




回答28:


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




回答29:


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.




回答30:


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;
}


来源:https://stackoverflow.com/questions/1529604/c-sharp-antipatterns

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!