C#反模式

长话短说:我发现Java反模式是不可或缺的资源。 对于初学者和专业人士一样多。 我还没有find这样的C#的东西。 所以我会把这个问题作为社区维基开放,并邀请大家分享他们的知识。 由于我是C#的新手,我对此非常感兴趣,但不能从一些反模式开始:/

这里是我发现C#而不是其他语言的答案。

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


抛出NullReferenceException

抛出exception:

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

属性与公共variables

类中的公共variables(改为使用属性)。

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


不理解,布尔是一个真正的types,不只是一个约定

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

或者甚至更好

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

像这样的构造经常被CC++开发者使用,其中布尔值的概念只是一个约定(0 == false,其他都是真的)。 这在C#或其他有实际布尔值的语言中是没有必要的(或可取的)。


使用using()

在适当情况下不使用:

 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. 

重新发现exception错误。 重新抛出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 } 

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

我在Java和C#中看到了这种方式太多了。

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

如果还有奖励积分

 else{ somethingelse = false; } 
 using Microsoft.SharePoint; 

“nuff说

我看到很多以下代码:

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

应该:

  return (i==3); 

侮辱德米特的法律:

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

抛出NullReferenceException

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

这是真的,我亲眼所见。

 public object GetNull() { return null; } 

它实际上是在应用程序中使用,甚至有一个存储过程,以及它也是一个sp_GetNull,将返回null ….

这是我的一天。

我认为sp是用于一个经典的asp网站..结果集。 .net之一是有人的想法“转换”到.net的代码…

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

或者更一般的情况:

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

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

 DateTime date = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day); 

很多时候我偶然发现了这种滥用滥用的情况:

 var ok = Bar(); 

甚至更好:

 var i = AnyThing(); 

使用var这种方式没有任何意义,也没有任何收获。 它只是使代码更难以遵循。

  • 在委托调用之前缺less空testing 。
  • 不知道什么时候以及如何使用'as'与一个空检查与一个try / catch的转换。
  • 在catch块中抛出exception与抛出。
  • 实例化大量的string,而不是使用StringBuilder。
  • 使用块的深度嵌套 。

不理解,布尔是一个真正的types,不只是一个约定

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

或者甚至更好

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

像这样的构造经常被CC++开发者使用,其中布尔值的概念只是一个约定(0 == false,其他都是真的)。 这在C#或其他有真正的布尔值的语言中是没有必要的(或可取的)。

更新 :修改了最后一段以提高清晰度。

类中的公共variables(改为使用属性)。

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

请参阅下面的评论以供讨论和澄清。

我已经看到了这一点。

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

击败isAvailable == true反模式双手!
这是一个超级反模式!

 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. 

私有自动执行的属性:

 private Boolean MenuExtended { get; set; } 

在每个方法的顶部声明和初始化所有局部variables是非常难看的!

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

两个string反模式
反模式#1
检查string是否为空或空

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

反模式#2 (仅适用于.NET 4.0)
检查string是否为空或空白或空格

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

不必投的(请相信编译器):

 foreach (UserControl view in workspace.SmartParts) { UserControl userControl = (UserControl)view; views.Add(userControl); } 
 if(data != null) { variable = data; } else { variable = new Data(); } 

可以写得更好

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

甚至写得更好

 variable = data ?? new Data(); 

最后的代码清单在.NET 2.0及更高版本中可用

用口音说话总是引起我的注意。

C ++程序员:

 if (1 == variable) { } 

在C#中,如果你inputif (1 = variable) ,会给你一个编译器错误,使你可以按照你的意思编写代码,而不用担心自己在脚下自己拍摄。

不使用三元的是我看到转换为C#偶尔做的事情

你看:

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

代替:

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

访问修改的closures

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

(请参阅链接解释和修复)

用于使用string连接而不是string生成器来连接任意数量的string

Exampls

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

这被认为是一般?

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

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

我正在进行的这个项目有五十个class级,都是从同一class级inheritance而来的,

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

要么把它放在父类中,要么把它放在一边。 哎呀。

你有没有考虑浏览每日跆拳道 ?

大量过度复杂的“Page_Load”方法,它们想要做的一切。

使用属性除了简单地检索一个值或可能是一个便宜的计算。 如果您正在从属性访问数据库,则应将其更改为方法调用。 开发人员期望这种方法调用可能代价很高,他们并不期望这些属性。

Found this a few times in a system I inherited…

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

反之亦然

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