C# if-null-then-null expression

前端 未结 6 1927
误落风尘
误落风尘 2020-12-01 02:56

Just for curiosity/convenience: C# provides two cool conditional expression features I know of:

string trimmed = (input == null) ? null : input.Trim();


        
相关标签:
6条回答
  • 2020-12-01 03:03

    As a workaround you can use this which is based on Maybe monad.

    public static Tout IfNotNull<Tin, Tout>(this Tin instance, Func<Tin, Tout> Output)
    {
        if (instance == null)
            return default(Tout);
        else
            return Output(instance);
    }
    

    Use it this way:

    int result = objectInstance.IfNotNull(r => 5);
    var result = objectInstance.IfNotNull(r => r.DoSomething());
    
    0 讨论(0)
  • 2020-12-01 03:04

    Something like Groovy's null-safe dereferencing operator?

    string zipCode = customer?.Address?.ZipCode;
    

    I gather that the C# team has looked at this and found that it's not as simple to design elegantly as one might expect... although I haven't heard about the details of the problems.

    I don't believe there's any such thing in the language at the moment, I'm afraid... and I haven't heard of any plans for it, although that's not to say it won't happen at some point.

    EDIT: It's now going to be part of C# 6, as the "null-conditional operator".

    0 讨论(0)
  • 2020-12-01 03:04

    Currently we can only write an extension method if you don't want to repeat yourself, I'm afraid.

    public static string NullableTrim(this string s)
    {
       return s == null ? null : s.Trim();
    }
    
    0 讨论(0)
  • 2020-12-01 03:10

    I had the same problem I wrote a few little extension methods:

    public static TResult WhenNotNull<T, TResult>(
        this T subject, 
        Func<T, TResult> expression)
        where T : class
    {
        if (subject == null) return default(TResult);
        return expression(subject);
    }
    
    public static TResult WhenNotNull<T, TResult>(
        this T subject, Func<T, TResult> expression,
        TResult defaultValue)
        where T : class
    {
        if (subject == null) return defaultValue;
        return expression(subject);
    }
    
    public static void WhenNotNull<T>(this T subject, Action<T> expression)
        where T : class
    {
        if (subject != null)
        {
            expression(subject);
        }
    }
    

    You use it like this;

    string str = null;
    return str.WhenNotNull(x => x.Length);
    

    or

    IEnumerable<object> list;
    return list.FirstOrDefault().WhenNotNull(x => x.id, -1);
    

    or

    object obj;
    IOptionalStuff optional = obj as IOptionalStuff;
    optional.WhenNotNull(x => x.Do());
    

    There are also overloads for nullable types.

    0 讨论(0)
  • 2020-12-01 03:16

    You can choose between a custom Nullify class or a NullSafe extension method as described here: http://qualityofdata.com/2011/01/27/nullsafe-dereference-operator-in-c/

    The usage will be as follows:

    //Groovy:
    bossName = Employee?.Supervisor?.Manager?.Boss?.Name
    
    //C# Option 1:
    bossName = Nullify.Get(Employee, e => e.Supervisor, s => s.Manager,
                           m => m.Boss, b => b.Name);
    //C# Option 2:
    bossName = Employee.NullSafe( e => e.Supervisor ).NullSafe( s => s.Boss )
                          .NullSafe( b => b.Name );
    
    0 讨论(0)
  • 2020-12-01 03:24

    There's nothing built-in, but you could wrap it all up in an extension method if you wanted (although I probably wouldn't bother).

    For this specific example:

    string trimmed = input.NullSafeTrim();
    
    // ...
    
    public static class StringExtensions
    {
        public static string NullSafeTrim(this string source)
        {
            if (source == null)
                return source;    // or return an empty string if you prefer
    
            return source.Trim();
        }
    }
    

    Or a more general-purpose version:

    string trimmed = input.IfNotNull(s => s.Trim());
    
    // ...
    
    public static class YourExtensions
    {
        public static TResult IfNotNull<TSource, TResult>(
            this TSource source, Func<TSource, TResult> func)
        {
            if (func == null)
                throw new ArgumentNullException("func");
    
            if (source == null)
                return source;
    
            return func(source);
        }
    }
    
    0 讨论(0)
提交回复
热议问题