What is the proper way to check for null values?

前端 未结 10 1980
刺人心
刺人心 2020-12-04 08:05

I love the null-coalescing operator because it makes it easy to assign a default value for nullable types.

 int y = x ?? -1;

That\'s great,

相关标签:
10条回答
  • 2020-12-04 08:51

    All of the suggested solutions are good, and answer the question; so this is just to extend on it slightly. Currently the majority of answers only deal with null validation and string types. You could extend the StateBag object to include a generic GetValueOrDefault method, similar to the answer posted by Jon Skeet.

    A simple generic extension method that accepts a string as a key, and then type checks the session object. If the object is null or not the same type, the default is returned, otherwise the session value is returned strongly typed.

    Something like this

    /// <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;
    }
    
    0 讨论(0)
  • 2020-12-04 08:51

    We use a method called NullOr.

    Usage

    // 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());
    

    Source

    /// <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();
        }
    }
    
    0 讨论(0)
  • 2020-12-04 08:51

    This is my little type safe "Elvis operator" for versions of .NET that do not support ?.

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

    First argument is the tested object. Second is the function. And third is the null value. So for your case:

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

    It is very useful for nullable types too. For example:

    decimal? v;
    ...
    IsNull.Substitute(v,v.Value,0);
    ....
    
    0 讨论(0)
  • 2020-12-04 08:53

    Skeet's answer is the best - in particularly I think his ToStringOrNull() is quite elegant and suits your need best. I wanted to add one more option to the list of extension methods:

    Return original object or default string value for 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");
    

    Use var for the returned value as it will come back as the original input's type, only as the default string when null

    0 讨论(0)
提交回复
热议问题