c#プログラマーへの10の重要なヒント

8771 ワード

本稿では、c#プログラマーにとって最も重要な10のヒントについて説明します.各ヒントには対応するコードがあり、初心者にとっても把握しやすいと思います.

1:非公開の方法のテスト作成


コンポーネントの非公開方法のテストを書いてみたことがありますか?多くの開発者は書いたことがありません.これらの方法はテストプロジェクトにとって見えないからです.c#はAssemblyInfo.csに次のタグ(InternalsVisibleToAttribute)を追加し、内部メンバーが他のコンポーネントに表示されます.
//Make the internals visible to the test assembly [assembly: InternalsVisibleTo("MyTestAssembly")]

2:Tuplesタイプを使う


関数が複数の値を返すだけでPOCOクラスを作成する人を見たことがあるが、実際には.Net 4.0のTuplesタイプは、次のようなより適切です.
public Tuple<int, string, string> GetEmployee() { int employeeId = 1001; string firstName = "Rudy"; string lastName = "Koertson"; //Create a tuple and return return Tuple.Create(employeeId, firstName, lastName);
}

3:一時集合の代わりにyieldを使用


集合からメンバーの一部を選択すると、通常、メンバーを保存して返す一時集合/リストが作成されます.たとえば、次のコードなどです.
public List<int> GetValuesGreaterThan100(List<int> masterCollection) {
    List<int> tempResult = new List<int>(); foreach (var value in masterCollection) { if (value > 100) {
            tempResult.Add(value);
        }
    } return tempResult;
}

このような一時的な集合を回避するには、yieldキーワードを使用します.例は次のとおりです.
public IEnumerable<int> GetValuesGreaterThan100(List<int> masterCollection) { foreach (var value in masterCollection) { if (value > 100) { yield return value;
        }
    }
}

もちろん、LINQを使って上記の問題を解決することもできます.

4:代替方法を他の人に伝える


コンポーネントがある場合、メソッドの1つを置き換える場合は、まずメソッドに古いタグを追加してクライアントに通知できます.サンプルコードは次のとおりです.
[Obsolete("This method will be deprecated soon. You could use XYZ alternatively.")] public void MyComponentLegacyMethod() { //Here is the implementation }

このメソッドを使用すると、クライアントはコンパイル時に警告を発行します.クライアントが古いメソッドを使用することを許可しなくなった場合、古いタグに追加のブールパラメータを追加できます.次の例では、クライアントはコンパイルに失敗します.
[Obsolete("This method is deprecated. You could use XYZ alternatively.", true)] public void MyComponentLegacyMethod() { //Here is the implementation }

5:LINQクエリは遅延実行であることを肝に銘じてください


はい.NETでLINQクエリーを作成する場合、LINQクエリーの結果にアクセスすると、LINQクエリーが実行されます.LINQのこのような特徴は遅延実行と呼ばれますが、結果にアクセスするたびにLINQクエリーが実行されることに注意してください.
LINQクエリの繰り返し実行を回避するには、次のようにクエリをリストに変換します.
public void MyComponentLegacyMethod(List<int> masterCollection) { //  ,   ToList , LINQ   var result = masterCollection.Where(i => i > 100).ToList();
    Console.WriteLine(result.Count());
    Console.WriteLine(result.Average());
}

6:explicitキーワードを使用してビジネスエンティティタイプを変換


explicitキーワードを使用してビジネス・エンティティ・タイプ間の変換を定義します.コードにタイプ変換要求が表示されると、変換方法が自動的に実行されます.次に、サンプル・コードを示します.
class Program { static void Main(string[] args) { var entity = new ExternalEntity {
            Id = 1001,
            FirstName = "Dave",
            LastName = "Johnson" }; var convertedEntity = (MyEntity)entity;
    }
} class MyEntity { public int Id { get; set; } public string FullName { get; set; } public static explicit operator MyEntity(ExternalEntity externalEntity) { return new MyEntity {
            Id = externalEntity.Id,
            FullName = externalEntity.FirstName + " " + externalEntity.LastName
        };
    }
} class ExternalEntity { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; }
}

7:異常を保持する元のスタックトラッキング


c#コードでは、次のコードのようにcatchコードブロックにConnectDatabaseメソッドで発生した異常を投げ出すと、異常スタックはRunDataOperationメソッドにのみ表示され、異常元のスタック追跡情報が失われ、正確なエラーソースが見つかりません.
public void RunDataOperation() { try {
        Intialize();
        ConnectDatabase();
        Execute();
    } catch (Exception exception) { throw exception;
    }
}

元のスタックトラッキングを維持するコードは次のとおりです.
public void RunDataOperation() { try {
        Intialize();
        ConnectDatabase();
        Execute();
    } catch (Exception) { throw;
    }
}

8:Flagsタグを使用して列挙をビットドメインとして処理


c#にFlagsタグを列挙タイプに追加すると、列挙はビットドメイン(すなわち、フラグのセット)として処理され、列挙値を自由に組み合わせることができます.サンプルコードは次のとおりです.
class Program { static void Main(string[] args) { int snakes = 14;
        Console.WriteLine((Reptile)snakes);
    }
}

[Flags] enum Reptile {
    BlackMamba = 2,
    CottonMouth = 4,
    Wiper = 8,
    Crocodile = 16,
    Aligator = 32 }

上のコードの出力は「BlackMamba,CottonMouth,Wiper」であり,Flagsタグがなければ上の出力は14である.

9:汎用型のタイプ制約を追加する


汎用タイプを作成する場合、指定した汎用タイプが指定したパラメータを実装する必要がある場合、または特定のベースクラスから継承する必要がある場合は、次のことができます.
class MyGenricClass<T> where T : IMyInterface { //Body of the class come in here }

もちろん、メソッドレベルでは、次のようにすることもできます.
class MyGenricClass { public void MyGenericMethod<T>(T t) where T : IMyInterface { //Generic implementation goes in here }

}

10:IEnumerableタイプは読み取り専用ではありません


作成したタイプでは、IEnumerableのタイプの読み取り専用プロパティが露出していますが、呼び出し元はタイプ変換でプロパティの内容を変更できます.たとえば、次のようにします.
class Program { static void Main(string[] args) {
        MyClass myClass = new MyClass();
        ((List<string>)myClass.ReadOnlyNameCollection).Add("######From Client#####");

        myClass.Print();
    }
} class MyClass {

    List<string> _nameCollection = new List<string>(); public MyClass() {
        _nameCollection.Add("Rob");
        _nameCollection.Add("John");
        _nameCollection.Add("Jummy");
        _nameCollection.Add("Derek");
    } public IEnumerable<string> ReadOnlyNameCollection { get { return _nameCollection.AsEnumerable(); }
    } public void Print() { foreach (var item in ReadOnlyNameCollection) {
            Console.WriteLine(item);
        }
    }
}

上のコードはリストを変更し、新しいアイテムを追加しました.これを回避するには、AsEnumerableではなくAsReadOnlyを使用します.
public IEnumerable<string> ReadOnlyNameCollection { get { return _nameCollection.AsReadOnly(); }
}

これらのヒントがあなたに役に立つことを望んでいます!
原文アドレス:Top 10 Tips for C#Programmers