C#反模式

C#反模式,c#,anti-patterns,C#,Anti Patterns,长话短说:我发现网络是不可或缺的资源。对于初学者和专业人士都是如此。我还没有为C#找到这样的东西。因此,我将以社区维基的形式打开这个问题,并邀请每个人分享他们在这方面的知识。由于我是C#的新手,我对此非常感兴趣,但不能从一些反模式开始:/ 以下是我认为对C语言特别适用的答案,而不是其他语言 我只是复制/粘贴了这些!考虑一下对这些评论的看法。 抛出错误的异常: if (FooLicenceKeyHolder == null) throw new NullReferenceExceptio

长话短说:我发现网络是不可或缺的资源。对于初学者和专业人士都是如此。我还没有为C#找到这样的东西。因此,我将以社区维基的形式打开这个问题,并邀请每个人分享他们在这方面的知识。由于我是C#的新手,我对此非常感兴趣,但不能从一些反模式开始:/

以下是我认为对C语言特别适用的答案,而不是其他语言

我只是复制/粘贴了这些!考虑一下对这些评论的看法。


抛出错误的异常:

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


类中的公共变量(改为使用属性)

除非该类是一个简单的数据传输对象


或者,甚至更好

if (myBooleanVariable != false)
{
    ...
}
if (myBooleanVariable != false)
{
    ...
}
像这样的构造通常被
C
C++
开发人员使用,其中布尔值的概念只是一种约定(0==false,其他都是true);这在C#或其他具有真正布尔值的语言中是不必要的(或不可取的)


不使用
在适当情况下使用

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.

类中的公共变量(改为使用属性)

除非该类是一个简单的数据传输对象

有关讨论和澄清,请参见下面的评论

或者更一般的情况:

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

这算是一般性的吗

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

我不知道如何解释它,但这就像有人捕捉到一个异常,然后一遍又一遍地重试代码,希望以后能正常工作。就像发生IOException一样,他们只是反复尝试,直到它起作用。

大量使用复杂的“页面加载”方法,这些方法想做任何事情。

GC.Collect()
收集,而不是信任垃圾收集器。

侮辱了德米特定律:

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.
a.PropertyA.PropertyC.PropertyB.PropertyE.PropertyA = 
     b.PropertyC.PropertyE.PropertyA;

错误地重新引发异常。要重新显示异常,请执行以下操作:

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
}

私有自动实现属性:

private Boolean MenuExtended { get; set; }
  • 不知道何时以及如何在空检查中使用“as”,而在try/catch中使用cast
  • catch块中的“抛出异常”与“抛出”
  • 实例化大量字符串,而不是使用StringBuilder

    • 我在我们的项目中发现了这个,差点把椅子弄坏

      DateTime date = new DateTime(DateTime.Today.Year, 
                                   DateTime.Today.Month, 
                                   DateTime.Today.Day);
      
      不必要的强制转换(请信任编译器):


      正在引发NullReferenceException

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

我说话总是带着口音

C++程序员:

if (1 == variable) { }

在C#中,如果键入
if(1=变量)
,这将给您一个编译器错误,允许您按照自己的意思编写代码,而不必担心会伤到自己。

在Java和C#中,我对这一点看得太多了

如果它也有额外的积分

else{
  somethingelse = false;
}

不明白布尔是一个真正的类型,而不仅仅是一个惯例

或者,甚至更好

if (myBooleanVariable != false)
{
    ...
}
if (myBooleanVariable != false)
{
    ...
}
像这样的构造通常被
C
C++
开发人员使用,其中布尔值的概念只是一种约定(0==false,其他都是true);这在C#或其他具有真正布尔值的语言中是不必要的(或不可取的)


更新:重新表述最后一段,以提高其清晰度。

在每个方法的顶部声明和初始化所有局部变量太难看了

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

    // Code
}

我经常会被这种var滥用绊倒:

var ok = Bar();
或者更好:

var i = AnyThing();

以这种方式使用var毫无意义,也一无所获。这只会使代码更难理解。

这是真的,我亲眼看到了

public object GetNull()
{
     return null;
}
它实际上是在应用程序中使用的,甚至还附带了一个存储过程,一个将返回null的sp_GetNull

这让我很开心


我认为sp用于一个经典的asp站点。。与结果集有关的内容。net是一个将代码“转换”为.net的想法…

使用属性进行任何操作,而不是简单地检索一个值或可能是一个便宜的计算。如果要从属性访问数据库,则应将其更改为方法调用。开发人员预计方法调用可能代价高昂,但他们不希望属性会这样

我经常看到以下代码:

if (i==3)
       return true;
else
       return false;
应该是:

       return (i==3);


(请参见链接以获取解释和修复)

我参与的项目有50个类,都继承自同一个类,它们都定义为:

要么把它放在父类中,要么把实用程序类放在一旁。啊


您是否考虑过浏览?

以使用字符串连接而不是字符串生成器来关联任意数量的字符串

范例

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

我看到转换成c#的人偶尔会这样做,不使用三元

你看,

private string foo = string.Empty;
if(someCondition)
  foo = "fapfapfap";
else
  foo = "squishsquishsquish";
而不是:

private string foo  = someCondition ? "fapfapfap" : "squishsquishsquish";

在我继承的系统中发现过几次

if(condition){
  some=code;
}
else
{
  //do nothing
}
反之亦然

if(condition){
  //do nothing
}
else
{
  some=code;
}
”努夫说

if(data != null)
{
  variable = data;
}
else
{
  variable = new Data();
}
可以更好地写成

variable = (data != null) ? data : new Data();
variable = data ?? new Data();
写得更好的是

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

最后一个代码清单在.NET2.0及更高版本中运行

我实际上已经看到了这一点

bool isAvailable = CheckIfAvailable();
if (isAvailable.Equals(true))
{ 
   //Do Something
}
轻松击败
isAvailable==true
反模式

让这成为一个超级反模式

两个字符串反模式
反模式#1
检查字符串是否为null或空

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

//Good
string.IsNullOrEmpty(myString)
反模式#2(仅适用于.NET 4.0)
检查字符串是否为空或空白

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

//Good
string.IsNullOrWhiteSpace(myString) 

这什么?为什么?-总部-你不可能告诉我有人做了这件事?实际上我已经从我们的代码库中重构了很多_o@matthew:添加了一个更一般的情况(来自datatable的aka,呵呵)是的,好的,我可以看到人们为一个对象这样做。但是对于一个
int
int
的作业……我没有骗你,我见过有人这样做,这是我经历过的许多WTF时刻之一。@Spence:
.Close()
不一定是“旧代码”。有些类提供了一个
Close()
方法作为
Dispose()
的别名,其中Close在语义上更有意义。True。但强制IDisposable允许您使用静态分析工具来发现实现ID的类型
variable = data ?? new Data();
bool isAvailable = CheckIfAvailable();
if (isAvailable.Equals(true))
{ 
   //Do Something
}
//Bad
if( myString == null || myString == "" )
OR
if( myString == null || myString.Length == 0 )

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

//Good
string.IsNullOrWhiteSpace(myString)