在异步上下文中使用Bind



我正在使用c#的' language-ext'包,试图使我们的代码更健壮,但在如何链接异步操作方面遇到困难。

考虑下面一个描述车辆的简单类的抽象示例

public class MyVehicle
{
public MyVehicle(string name)
{
Name = name;
}
public string Name { get; }
public MyVehicle DeepCopy()
{
return new MyVehicle(Name);
}
}

和另一个类存储关于车辆的一些状态

public class MyVehicleState
{
public MyVehicle CopiedVehicle { get; private set; }
public Option<int> EditingId { get; set; }
public void SetCopiedVehicle(MyVehicle vehicle)
{
CopiedVehicle = vehicle;
}
}

和用于检索车辆的车辆存储库

public class MyVehicleRepository
{
public Option<MyVehicle> GetVehicle(int id)
{
return id == 2 ? Some(new MyVehicle("Delorian")) : Option<MyVehicle>.None;
}
}

如果我想将MyVehicleState中复制的车辆属性设置为同一类中SelectedVehicleId定义的深度副本,我可以执行以下操作(不确定是否正确):

var state = new MyVehicleState
{
EditingId = Some(2)
};
var repo = new MyVehicleRepository();
state.EditingId
.Bind(vehicleId => repo.GetVehicle(vehicleId))
.Map(vehicle => vehicle.DeepCopy())
.IfSome(copiedVehicle => state.SetCopiedVehicle(copiedVehicle));

现在,如果我将车辆存储库更改为异步的,那么

public class MyVehicleRepository
{
public async Task<Option<MyVehicle>> GetVehicle(int id)
{
await Task.Delay(TimeSpan.FromSeconds(2));
return id == 2 ? Some(new MyVehicle("Delorian")) : Option<MyVehicle>.None;
}
}

我如何更新我的函数代码来做同样的事情,并在我的状态类中设置深度拷贝?

我已经尝试切换到BindAsync和使用MapAsync,但我似乎结束了一个输入,我需要打开两次,不确定如何进行(N.B.新的这个功能世界)。

下面的方法似乎有效,但这是最简洁的方法吗?

await state.EditingId
.MapAsync(async vehicleId => await repo.GetVehicle(vehicleId))
.IfSome(x => x
.Map(y => y.DeepCopy())
.IfSome(z => state.SetCopiedVehicle(z)));

如果你想平坦化一个函子,那么使用一元绑定。

这是我能想到的最简单的替代:

await state.EditingId
.BindAsync(i => repo.GetVehicle(i).ToAsync())
.Map(v => v.DeepCopy())
.Iter(state.SetCopiedVehicle);

ToAsync转换是必要的,因为它将Task<Option<MyVehicle>>转换为OptionAsync<MyVehicle>,随后的MapIter挂起。

最新更新