也许monad使用表达式树?

Bri*_*Low 5 .net c# null expression-trees

丑陋:

string city = null;
if (myOrder != null && myOrder.Customer != null)
  city = myOrder.Customer.City;
Run Code Online (Sandbox Code Playgroud)

更好(也许是monad):

var city = myOrder
               .With(x => x.Customer)
               .With(x => x.City)
Run Code Online (Sandbox Code Playgroud)

更好的?有什么理由不能写吗?

var city = Maybe(() => myOrder.Customer.City);
Run Code Online (Sandbox Code Playgroud)

LBu*_*kin 3

是的,这应该是可能的。然而,正确实现表达式树重写器比表面上看起来要复杂得多。特别是如果您希望能够正确处理字段、属性、索引属性、方法调用以及在任意表达式中有效的其他构造。

它也可能不是性能最好的操作,因为要计算表达式,您每次都必须将表达式树动态编译为 lambda 函数。

CodePlex 上有此模式的实现。我从未亲自使用过它,所以我不能说它的实现有多好,或者它是否可以处理我描述的所有情况。

创建表达式树重写器的另一种方法是编写Maybe()接受 lambda 函数(而不是表达式树)并捕获任何ArgumentNullException抛出的异常,并在这些情况下返回default(T)。以这种方式使用异常进行流量控制会让很多人感到不舒服……但这肯定是一个更容易正确实现的实现。我个人避免使用它,因为它可以掩盖作为表达式一部分调用的方法中的空引用错误,这是不可取的。