国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[小技巧]讓C#的空值處理變得更優雅

2019-11-17 02:54:16
字體:
來源:轉載
供稿:網友

[小技巧]讓C#的空值處理變得更優雅

參考

http://www.codePRoject.com/Articles/739772/Dynamically-Check-Nested-Values-for-IsNull-Values?msg=4895299#xx4895299xx

http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/

介紹

C#中的空值處理,一直是一件比較讓人不爽的工作。假設現在有如下類:

public class Union { public string Name { get; set; } }  public class Dep {        public Union Union { get; set; }        public string Name { get; set; } }  public  class Person    {        public  Dep Dep { get;set;}        public string Name { get; set; }    }

如果Person.Dep.Union.Name.Length>5,則寫入日志,代碼該怎么寫呢?很可能是這樣:

 if (person != null && person.Dep != null && person.Dep.Union != null && person.Dep.Union.Name != null && person.Dep.Union.Name.Length > 5)            {                Console.WriteLine(person.Dep.Union.Name);            }

邏輯語句寫得多的各位,對于這樣寫的繁瑣應該深有體會。

對策

1擴展方法在訪問對象前,會先進入其對應的靜態方法。可以很方便的對this參數進行判斷和處理,而不引起nullreference異常;

2委托可以很好的進行擴展方法的后續動作。

我們可以這樣寫上面的語句

             person                .GoTo(p => p.Dep.Union.Name)                .If(n => n.Length >= 5)                .Do(Console.WriteLine);

很簡潔,是不是?怎么實現呢?只需加入下列擴展類:

using System;using System.Linq;using System.Linq.Expressions;using System.Reflection;namespace LinqTesting{    public static class Helper    {        class IsNullVisitor : ExpressionVisitor        {            public bool IsNull { get; private set; }            public object CurrentObject { get; set; }            protected override Expression VisitMember(MemberExpression node)            {                //it will call this overrided method with higher level node                base.VisitMember(node);                if (CheckNull())                    return node;                var member = (PropertyInfo)node.Member;                CurrentObject = member.GetValue(CurrentObject, null);                CheckNull();                return node;            }            private bool CheckNull()            {                if (CurrentObject == null)                    IsNull = true;                return IsNull;            }        }        public static TReturn GoTo<T, TReturn>(this T root, Expression<Func<T, TReturn>> funcGetValue)        {            var visitor = new IsNullVisitor();            visitor.CurrentObject = root;            visitor.Visit(funcGetValue);            if (visitor.IsNull)                return default(TReturn);            return (TReturn)visitor.CurrentObject;        }        public static TInput If<TInput>(this TInput o, Func<TInput, bool> evaluator)          where TInput : class        {            if (o == null) return null;            return evaluator(o) ? o : null;        }        public static TInput Unless<TInput>(this TInput o, Func<TInput, bool> evaluator)          where TInput : class        {            if (o == null) return null;            return evaluator(o) ? null : o;        }        public static TInput Do<TInput>(this TInput o, Action<TInput> action)        where TInput : class        {            if (o == null) return null;            action(o);            return o;        }    }}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 富宁县| 花莲县| 克东县| 丹寨县| 开封县| 梧州市| 洪洞县| 萝北县| 噶尔县| 鹤山市| 浦北县| 临洮县| 东辽县| 金山区| 龙海市| 滕州市| 石城县| 天长市| 林西县| 鄂托克前旗| 无锡市| 长治县| 环江| 平原县| 微博| 阜南县| 彭水| 英超| 东光县| 濮阳县| 巴南区| 大埔区| 天气| 石阡县| 嘉祥县| 台州市| 景宁| 松溪县| 莒南县| 扎囊县| 南通市|