2

私は一般的に例外処理について考えてきました。

User指定されたユーザー名パラメーターに基づいてオブジェクトを取得するメソッドを実装するためのベストプラクティスは何でしょうか。下記参照。

    /// <summary>
    /// Gets a user.
    /// </summary>
    /// <param name="username">Username</param>
    /// <returns>User instance</returns>
    public Model.User GetUser(string username)
    {
        return Context.Users.SingleOrDefault(u => u.Username.ToLower() == username.ToLower());
    }

そのパラメータを持つユーザーが存在しない場合はusername、nullオブジェクトを返すUserか、ユーザーが存在しないことを指定するカスタム例外をスローする方がよいでしょう。

4

5 に答える 5

2

私のアドバイスは、プログラムがユーザーなしでは続行できない場合、例外をスローすることです。ユーザーが見つからない、またはログインに失敗しても問題ない場合は、null を返します。プログラムがユーザーを取得せずに続行できず、再度ログオンするようにリダイレクトできない場合にのみ、例外をスローします。

例外をスローすることは、null を返すより高価な操作であることを忘れないでください (目立たないことを意味し、このように考えます (マイクロ最適化) が、例外は通常のビジネス ロジックに使用する必要があります)。

于 2012-11-16T19:21:18.593 に答える
2

例外をスローします。そうしないと、呼び出し元、呼び出し元の呼び出し元、および他のすべての人が をチェックするnullか、空のコレクションを処理する必要があります。

これが汎用メソッドであり、呼び出し元が null をチェックする必要があることを知っているコンテキストで使用することを意図している場合は、これを少し異なる方法で行います。private一致するユーザーがいない場合は null を返すメソッドがあります。「try」パターンを使用する呼び出し元を追加します。

public bool TryGetUser(string username, out Model.User user)

また、単にユーザーを返すものもありますが、見つからない場合は例外をスローします

public Model.User GetUser(string username)
于 2012-11-16T19:23:34.283 に答える
1

まず、大文字と小文字を区別せずに文字列を比較する方法の改善を提案したいだけです。

/// <summary>
/// Gets a user.
/// </summary>
/// <param name="username">Username</param>
/// <returns>User instance</returns>
public Model.User GetUser(string username)
{
    return Context.Users.SingleOrDefault(u => 
       string.Compare(u.Username, username, true));
}

MSDN の String.Compare

今、この問題に関する私の提案

null を返すのではなく。null オブジェクト パターンを使用して、Null オブジェクトを返したい場合があります。

public class User
{

  public static readonly User Null = new Null{Username = "Anonymous"};

  ...

}

次に、メソッドは次のようになります。

public Model.User GetUser(string username)
{
    return Context.Users.SingleOrDefault(u => 
       string.Compare(u.Username, username, true)) ?? Model.User.Null;
}

nullこれは、望ましくない状況で役立ちます。null後で確認する必要がなくなります。たとえば、このユーザー オブジェクトに権限が関連付けられている場合、「null ユーザー」に権限がないことを確認できます。

于 2012-11-16T19:29:39.690 に答える
0

呼び出し元のメソッドは、ユーザーが見つからなかった結果に例外をスローする必要があるかどうかを判断できると言えます。ユーザー名が提供されているのに見つからない場合は、nullを返すことは私にとって意味があり、呼び出し元のコードに続行する必要がある方法を決定させることができます。

メソッドがどれほど一般的であるかを考えると、指定されたユーザー名が見つからない場合、なぜ例外をスローするのでしょうか。データベースエラーなどが発生した場合は1つですが、SELECTの結果が行にならなければ、例外ではないと思います。

于 2012-11-16T19:24:35.990 に答える
0

以前に投稿された回答に同意しません。

例外は、例外的な状況でのみ使用する必要があります。一致する値が見つからないことは例外ではありません。IMO、戻るnullことははるかにエレガントです。例外をスローするかどうかの決定は、呼び出し先ではなく呼び出し元に任せられます。これは理にかなっています。メソッドにユーザーを要求し、ユーザーが存在しない場合は何も返しません。

さらに、コードとその他の回答は毎回コレクション全体を反復処理するため、不必要に遅くなります。すばやく検索するには、辞書を使用する必要があります (もちろん、Users コレクションが頻繁に変更されてキャッシュが不可能になる場合は除きます)。

例:

class MyClass
{
    private Dictionary<String,User> _userLookup;

    public MyClass()
    {
        _userLookup = Context.Users.ToDictionary(u => u.UserName.ToLower());
    }

    private User getUserByName(String name)
    {
        var lowerName = name.ToLower();
        return _userLookup.ContainsKey(lowerName) ? _userLookup[lowerName] : null;
    }     
}
于 2013-01-04T18:41:37.123 に答える