[英]Avoid Null Checking by using lambdas
在本文中, 通过将出纳员替换为出纳员来避免空检查,作者提供了一个Ruby示例来避免空检查,如果返回了对象,则运行该块,否则返回。
data_source.person(id) do |person|
person.phone_number = phone_number
data_source.update_person person
end
我想使用Lambda函数在C#中执行相同的操作,但是想出一个执行相同类型操作的示例时遇到麻烦。 您是否将创建对象工厂以接受ID号以及lambda函数?
好吧,我不了解Ruby,也不了解给出的确切示例,但我怀疑这会是这样的:
dataSource.Update(id, person => person.PhoneNumber = phoneNumber);
其中DataSource.Update
将:
void Update(string id, Action<Person> updateAction
(或可能返回bool
以指示是否找到该人)之类的签名 或更笼统(更接近原始Ruby):
dataSource.WithPerson(id, person => {
person.PhoneNumber = phoneNumber;
dataSource.UpdatePerson(person);
};
就我个人而言,我更喜欢第一种形式:它更加详细地说明了要实现的目标,但这很可能有助于实现更好的实现,并且在调用代码中肯定更干净。
另一种方法是使用Maybe monad 。
这将允许您保持现有的API不变,即,您仍然可以具有dataSource.GetPersonById(id)
。
使用Maybe monad的代码如下所示:
dataSource.GetPersonById(id)
.Maybe()
.Do(person => {
person.PhoneNumber = phoneNumber;
dataSource.UpdatePerson(person);
});
为了能够使用Maybe monad,您需要在以下段落中具有代码。
它的基础是Daniel Earwicker链接的博客文章中的代码。
我对其进行了扩展,以添加Maybe
扩展方法并进行编译。
public struct MaybeMonad<T> where T : class
{
private readonly T _value;
public MaybeMonad(T value)
{
_value = value;
}
public MaybeMonad<TResult> Select<TResult>(Func<T, TResult> getter)
where TResult : class
{
var result = (_value == null) ? null : getter(_value);
return new MaybeMonad<TResult>(result);
}
public TResult Select<TResult>(Func<T, TResult> getter,
TResult alternative)
{
return (_value == null) ? alternative : getter(_value);
}
public void Do(Action<T> action)
{
if (_value != null)
action(_value);
}
}
public static class Maybe
{
public static MaybeMonad<T> From<T>(T value) where T : class
{
return new MaybeMonad<T>(value);
}
}
public static class MaybeMonadExtensions
{
public static MaybeMonad<T> Maybe<T>(this T value) where T : class
{
return new MaybeMonad<T>(value);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.