web-dev-qa-db-ja.com

C#アンチパターン

簡単に言えば、 Javaアンチパターン は不可欠なリソースです。初心者から専門家まで。 C#でこのようなものをまだ見つけていません。そこで、この質問をコミュニティWikiとして公開し、全員にこのことに関する知識を共有してもらいます。私はC#が初めてなので、これに非常に興味がありますが、いくつかのアンチパターンから始めることはできません:/

以下は、他の言語ではなくC#に特に当てはまる答えです。

これらをコピー/ペーストしただけです!これらについてのコメントも見てみてください。


NullReferenceExceptionを投げる

間違った例外を投げる:

_if (FooLicenceKeyHolder == null)
    throw new NullReferenceException();
_

プロパティとパブリック変数

クラス内のパブリック変数(代わりにプロパティを使用します)。

Unlessクラスは単純なデータ転送オブジェクトです。


boolが単なる規則ではなく、実際の型であることを理解していない

_if (myBooleanVariable == true)
{
    ...
}
_

または、さらに良い

_if (myBooleanVariable != false)
{
    ...
}
_

このような構造は、ブール値の概念が単なる慣習であるCおよび_C++_開発者によってよく使用されます(0 == false、その他はすべて真)。これは、C#または真のブール値を持つ他の言語では必要ありません(または望ましくありません)。


using()を使用

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.
_
55
exhuma

例外を誤って再スローします。例外を再スローするには:

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
}
62
rein

ガベージコレクターを信頼する代わりに収集するGC.Collect()

40
Andrew Keith

JavaとC#...

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

ボーナスポイントも持っている場合

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

'言っ途切れる

25
Rubens Farias

私は次のコードをたくさん見ます:

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

する必要があります:

       return (i==3);
22
Benny

デメテルの法則をIn辱する:

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

NullReferenceExceptionを投げる:

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

これは本当です、私は自分の目で見ました。

public object GetNull()
{
     return null;
}

それは実際にアプリで使用され、さらにそれと一緒に行くためのストアドプロシージャ、nullを返すsp_GetNullさえも持っていました。

それは私の一日を作りました。

私はspが古典的なASPサイトに使用されたと思います..結果セットと関係があります。 .netのものは、コードを.netに「変換」する誰かのアイデアでした...

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

または、より一般的な場合:

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

私たちのプロジェクトでこれを見つけて、椅子をほとんど壊しました...

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

私はこの種のvar-abuseにつまずくことがよくあります。

var ok = Bar();

またはさらに良い:

var i = AnyThing();

Varをそのように使用しても意味がなく、何も得られません。コードを追跡するのが難しくなります。

11
10
anthony

Boolは単なる慣習ではなく実際の型であることを理解していない

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

または、さらに良い

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

これらのような構造は、ブール値の概念が単なる慣習であるCおよびC++開発者によってよく使用されます(0 == false、その他はすべて真)。これは、C#または真のブール値を持つ他の言語では必要ありません(または望ましくありません)。

更新:わかりやすくするために最後の段落を言い換えました。

10
Bevan

クラス内のパブリック変数(代わりにプロパティを使用します)。

nlessクラスは単純なデータ転送オブジェクトです。

議論と説明については、以下のコメントを参照してください。

9
Robert Harvey

私は実際にこれを見ました。

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

isAvailable == trueアンチパターンの伝承!
これを超アンチパターンにします!

8
Binoj Antony
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.
6
Spence

プライベート自動実装プロパティ:

private Boolean MenuExtended { get; set; }
6
leppie

2つのストリングアンチパターン
アンチパターン#1
nullまたは空の文字列をチェック

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

//Good
string.IsNullOrEmpty(myString)

Anti-Pattern#2(.NET 4.0のみ)
null、空、または空白の文字列の確認

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

//Good
string.IsNullOrWhiteSpace(myString) 
6
Binoj Antony

各メソッドの上部ですべてのローカル変数を宣言して初期化するのは非常に面倒です!

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

    // Code
}
6

不必要なキャスト(コンパイラを信頼してください):

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

次のように書くことができます

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

さらに良いように書かれて

variable = data ?? new Data();

最後のコードリストは.NET 2.0以降で機能します

5
Binoj Antony

アクセントで話すことは常に私をキャッチしました。

C++プログラマー:

_if (1 == variable) { }
_

C#では、if (1 = variable)と入力するとコンパイラエラーが発生し、足を踏み入れることを心配する代わりに、意図したとおりにコードを記述できます。

4
Spence

ターナリーを使用しないことは、時々c#に変換されることがあります

分かりますか:

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

の代わりに:

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

Stringbuilderの代わりに文字列連結を使用して任意の数の文字列を連結する場合

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

変更されたクロージャーへのアクセス

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

(説明と修正についてはリンクを参照してください)

3
Greg

これは一般的と見なされますか?

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

私はそれを説明する方法を知りませんが、誰かが例外をキャッチし、後で動作することを何度も何度も再試行するようなものです。 IOExceptionが発生した場合と同様に、動作するまで何度も試行します。

2
Andrew Keith

私が取り組んでいるプロジェクトには、同じクラスから継承する50のクラスがあり、allが定義されています:

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

親クラスに入れるか、ユーティリティクラスを脇に置きます。ああ。

The Daily WTF の閲覧を検討しましたか?

2
Dean J

私が継承したシステムでこれを数回見つけました...

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

およびその逆

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

非常に複雑な「Page_Load」メソッド。すべてを実行したい。

1
Ralph Lavelle

私はこれを前に持っていました:

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

stateは、列挙RowStateからの値を含む文字列ポスト値です。

最終的に、これは値に対してチェックするために使用する方法です。

1

単に値を取得するためだけでなく、場合によっては安価な計算以外の目的でプロパティを使用する。プロパティからデータベースにアクセスしている場合は、メソッド呼び出しに変更する必要があります。開発者は、メソッド呼び出しにコストがかかる可能性があることを期待していますが、プロパティからこれを期待していません。

1
triskelion

.NETの主な問題は、VB 6.0または(さらに悪いことには、VB 6.0プログラマーは、少なくとも新しいことを学ぼうとするほど謙虚です)Java/C++。

現代のパラダイムに対して無知すぎる人々、可能な限り最悪のC++スタイルでcodeいP/Invokeでコードを塗りつぶしている人々。 :-(

1

無知は至福です(フレームワークを知ってください):

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

int daysLeft = keyDays.Days - nowDays.Days;
0
leppie

使用(悪い)

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

代わりに(良い)

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

iEnumerableに何かが含まれているかどうかをテストする。 Count()MoveNext()を使用してコレクション全体を列挙する必要がありますが、Any()MoveNext()を1回呼び出すだけです。

0
Mark Nelson

私は最近いくつかを見ました。

終了しないパラメータチェーン

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
    }

フォームを閉じるときに何が起こるか

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

文字列型

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;
0
Raghu

プロパティをコーディングするときは、その使用を考えずにゲッターとセッターを自動的に与えるだけです。多くの場合、getまたはsetは使用されず、プロパティは読み取り(get)のみ、または書き込み(set)のみにする必要があります。

0
bytedev