122

null許容型にデフォルト値を簡単に割り当てることができるので、null合体演算子が大好きです。

 int y = x ?? -1;

で簡単なことをする必要がある場合を除いて、それは素晴らしいことですx。たとえば、を確認したい場合は、Session通常、より冗長なものを作成する必要があります。

私はこれができたらいいのにと思います:

string y = Session["key"].ToString() ?? "none";

ただし.ToString()、nullチェックの前にgetsが呼び出されるため、がnullの場合Session["key"]は失敗します。私はこれを行うことになります:

string y = Session["key"] == null ? "none" : Session["key"].ToString();

私の意見では、これは機能し、3行の代替案よりも優れています。

string y = "none";
if (Session["key"] != null)
    y = Session["key"].ToString();

それはうまくいきますが、もっと良い方法があるかどうか私はまだ興味があります。私がいつもSession["key"]2回参照しなければならないことは問題ではないようです。1回はチェック用、もう1回は割り当て用です。何か案は?

4

10 に答える 10

182

どうですか

string y = (Session["key"] ?? "none").ToString();
于 2012-03-20T14:12:47.907 に答える
130

特にToString()これを頻繁に行う場合は、拡張メソッドを作成できます。

public static string NullPreservingToString(this object input)
{
    return input == null ? null : input.ToString();
}

...

string y = Session["key"].NullPreservingToString() ?? "none";

または、もちろん、デフォルトを使用するメソッド:

public static string ToStringOrDefault(this object input, string defaultValue)
{
    return input == null ? defaultValue : input.ToString();
}

...

string y = Session["key"].ToStringOrDefault("none");
于 2012-03-20T14:14:32.383 に答える
21

を使用することもできます。これは、変換が失敗した場合asに生成されます。null

Session["key"] as string ?? "none"

"none"誰かがを詰め込んだとしても、intこれは戻りSession["key"]ます。

于 2012-03-20T18:36:11.907 に答える
13

常にである場合は、次のstringようにキャストできます。

string y = (string)Session["key"] ?? "none";

これには、誰かがint何かを詰め込んだ場合に間違いを隠すのではなく、不平を言うという利点がありSession["key"]ます。;)

于 2012-03-20T14:15:38.013 に答える
10

提案された解決策はすべて優れており、質問に答えます。ですから、これはほんの少しだけ拡張するためのものです。現在、回答の大部分はnull検証と文字列タイプのみを扱っています。Jon Skeetによって投稿された回答と同様に、オブジェクトを拡張しStateBagてジェネリックメソッドを含めることができます。GetValueOrDefault

文字列をキーとして受け取り、セッションオブジェクトを型チェックする単純なジェネリック拡張メソッド。オブジェクトがnullであるか、同じタイプでない場合は、デフォルトが返されます。それ以外の場合は、セッション値が強く型付けされて返されます。

このようなもの

/// <summary>
/// Gets a value from the current session, if the type is correct and present
/// </summary>
/// <param name="key">The session key</param>
/// <param name="defaultValue">The default value</param>
/// <returns>Returns a strongly typed session object, or default value</returns>
public static T GetValueOrDefault<T>(this HttpSessionState source, string key, T defaultValue)
{
    // check if the session object exists, and is of the correct type
    object value = source[key]
    if (value == null || !(value is T))
    {
        return defaultValue;
    }

    // return the session object
    return (T)value;
}
于 2012-03-20T16:53:21.870 に答える
7

と呼ばれるメソッドを使用しますNullOr

使用法

// Call ToString() if it’s not null, otherwise return null
var str = myObj.NullOr(obj => obj.ToString());

// Supply default value for when it’s null
var str = myObj.NullOr(obj => obj.ToString()) ?? "none";

// Works with nullable return values, too —
// this is properly typed as “int?” (nullable int)
// even if “Count” is just int
var count = myCollection.NullOr(coll => coll.Count);

// Works with nullable input types, too
int? unsure = 47;
var sure = unsure.NullOr(i => i.ToString());

ソース

/// <summary>Provides a function delegate that accepts only value types as return types.</summary>
/// <remarks>This type was introduced to make <see cref="ObjectExtensions.NullOr{TInput,TResult}(TInput,FuncStruct{TInput,TResult})"/>
/// work without clashing with <see cref="ObjectExtensions.NullOr{TInput,TResult}(TInput,FuncClass{TInput,TResult})"/>.</remarks>
public delegate TResult FuncStruct<in TInput, TResult>(TInput input) where TResult : struct;

/// <summary>Provides a function delegate that accepts only reference types as return types.</summary>
/// <remarks>This type was introduced to make <see cref="ObjectExtensions.NullOr{TInput,TResult}(TInput,FuncClass{TInput,TResult})"/>
/// work without clashing with <see cref="ObjectExtensions.NullOr{TInput,TResult}(TInput,FuncStruct{TInput,TResult})"/>.</remarks>
public delegate TResult FuncClass<in TInput, TResult>(TInput input) where TResult : class;

/// <summary>Provides extension methods that apply to all types.</summary>
public static class ObjectExtensions
{
    /// <summary>Returns null if the input is null, otherwise the result of the specified lambda when applied to the input.</summary>
    /// <typeparam name="TInput">Type of the input value.</typeparam>
    /// <typeparam name="TResult">Type of the result from the lambda.</typeparam>
    /// <param name="input">Input value to check for null.</param>
    /// <param name="lambda">Function to apply the input value to if it is not null.</param>
    public static TResult NullOr<TInput, TResult>(this TInput input, FuncClass<TInput, TResult> lambda) where TResult : class
    {
        return input == null ? null : lambda(input);
    }

    /// <summary>Returns null if the input is null, otherwise the result of the specified lambda when applied to the input.</summary>
    /// <typeparam name="TInput">Type of the input value.</typeparam>
    /// <typeparam name="TResult">Type of the result from the lambda.</typeparam>
    /// <param name="input">Input value to check for null.</param>
    /// <param name="lambda">Function to apply the input value to if it is not null.</param>
    public static TResult? NullOr<TInput, TResult>(this TInput input, Func<TInput, TResult?> lambda) where TResult : struct
    {
        return input == null ? null : lambda(input);
    }

    /// <summary>Returns null if the input is null, otherwise the result of the specified lambda when applied to the input.</summary>
    /// <typeparam name="TInput">Type of the input value.</typeparam>
    /// <typeparam name="TResult">Type of the result from the lambda.</typeparam>
    /// <param name="input">Input value to check for null.</param>
    /// <param name="lambda">Function to apply the input value to if it is not null.</param>
    public static TResult? NullOr<TInput, TResult>(this TInput input, FuncStruct<TInput, TResult> lambda) where TResult : struct
    {
        return input == null ? null : lambda(input).Nullable();
    }
}
于 2012-03-22T15:32:26.540 に答える
6

私の好みは、キーとともに保存されているオブジェクトが1つでない場合に備えて、文字列への安全なキャストを使用することです。を使用ToString()すると、希望する結果が得られない場合があります。

var y = Session["key"] as string ?? "none";

@Jon Skeetが言うように、これを頻繁に実行している場合は、拡張メソッド、またはより良いのは、厳密に型指定されたSessionWrapperクラスと組み合わせた拡張メソッドです。拡張メソッドがなくても、強く型付けされたラッパーは良い考えかもしれません。

public class SessionWrapper
{
    private HttpSessionBase Session { get; set; }

    public SessionWrapper( HttpSessionBase session )
    {
        Session = session;
    }

    public SessionWrapper() : this( HttpContext.Current.Session ) { }

    public string Key
    {
         get { return Session["key"] as string ?? "none";
    }

    public int MaxAllowed
    {
         get { return Session["maxAllowed"] as int? ?? 10 }
    }
}

使用されます

 var session = new SessionWrapper(Session);

 string key = session.Key;
 int maxAllowed = session.maxAllowed;
于 2012-03-20T19:12:20.170 に答える
3

補助機能を作成する

public static String GetValue( string key, string default )
{
    if ( Session[ key ] == null ) { return default; }
    return Session[ key ].toString();
}


string y = GetValue( 'key', 'none' );
于 2012-03-20T14:14:02.820 に答える
2

スキートの答えは最高です-特に彼ToStringOrNull()は非常にエレガントであなたのニーズに最も合っていると思います。拡張メソッドのリストにもう1つのオプションを追加したかったのです。

nullの元のオブジェクトまたはデフォルトの文字列値を返します。

// Method:
public static object OrNullAsString(this object input, string defaultValue)
{
    if (defaultValue == null)
        throw new ArgumentNullException("defaultValue");
    return input == null ? defaultValue : input;
}

// Example:
var y = Session["key"].OrNullAsString("defaultValue");

var元の入力のタイプとして返​​されるため、戻り値に使用します。デフォルトの文字列としてのみ使用します。null

于 2012-03-20T18:35:29.130 に答える
0

これは、?をサポートしないバージョンの.NET用の私の小さなタイプセーフな「エルビス演算子」です。

public class IsNull
{
    public static O Substitute<I,O>(I obj, Func<I,O> fn, O nullValue=default(O))
    {
        if (obj == null)
            return nullValue;
        else
            return fn(obj);
    }
}

最初の引数はテストされたオブジェクトです。2番目は機能です。そして3番目はnull値です。だからあなたの場合:

IsNull.Substitute(Session["key"],s=>s.ToString(),"none");

null許容型にも非常に役立ちます。例えば:

decimal? v;
...
IsNull.Substitute(v,v.Value,0);
....
于 2016-06-01T08:57:00.457 に答える