使用lambdas避免空检查
本文关键字:检查 lambdas 使用 | 更新日期: 2023-09-27 18:20:49
在本文中,通过用teller替换finder来避免空检查作者给出了一个Ruby示例来避免null检查,如果返回对象,则块运行,如果不返回,则块不运行。
data_source.person(id) do |person|
person.phone_number = phone_number
data_source.update_person person
end
我想在C#中使用lambda函数做同样的事情,但我很难想出一个做同样类型事情的例子。你会创建对象工厂来接受id号和lambda函数吗?
我不了解Ruby,也不理解给出的确切例子,但我怀疑它会像:
dataSource.Update(id, person => person.PhoneNumber = phoneNumber);
其中DataSource.Update
将:
- 有一个类似
void Update(string id, Action<Person> updateAction
的签名(或者可能返回一个bool
来指示它是否找到了这个人) - 实施方式:
- 找到具有给定ID的人
- 如果不存在,请立即返回
- 否则,执行给定的操作,并使用修改后的对象更新后备存储
或者更普遍地(更接近原始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);
}
}