如何用语言ext简化c#中的错误传播,类似于rust?操作员?

发布于 2025-02-06 21:06:49 字数 1593 浏览 1 评论 0原文

任何人都知道在C#中使用,类似于Rust具有的错误传播操作员?

例如,我想在下面简化创建方法中的错误处理:

using LanguageExt;
using LanguageExt.Common;

using static LanguageExt.Prelude;

public class ProductAggregate
{
    public string Name { get; private set; } = string.Empty;

    public static Fin<ProductAggregate> Create(string name)
    {
        var product = new ProductAggregate();

        // I find this too verbose and looking to simplify:
        if (product.SetName(name) is { IsFail: true } errFin)
        {
            return (Error)errFin;
        }

        return product;
    }

    public Fin<Unit> SetName(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            return Error.New("Product name cannot be null or empty.");
        }

        Name = name;

        return unit;
    }
}

有什么办法可以缩短它?我真的很喜欢这是如何生锈的:

fn get_current_date() -> Result<String, reqwest::Error> {
  let url = "https://postman-echo.com/time/object";
  let res = reqwest::blocking::get(url)?.json::<HashMap<String, i32>>()?;
  let date = res["years"].to_string();
  Ok(date)
}

上面的操作员通过进一步的步骤链接,但是基本上,它基本上检查左会员还是呼叫返回是错误结果,然后返回该错误。当然,它必须匹配封装函数的返回类型的错误类型(reqwest ::错误)。

有没有办法实现与此类优雅的接近的东西,但是在C#中?

编辑:试图接受Mark Seemann关于代码的建议,该建议应提供最小,可重复的例子。

Is anyone aware of a way to simplify error handling when doing functional programming in C# using the Language-Ext library, similar to the error propagation operator that Rust has?

For example, I want to simplify the error handling in the Create method below:

using LanguageExt;
using LanguageExt.Common;

using static LanguageExt.Prelude;

public class ProductAggregate
{
    public string Name { get; private set; } = string.Empty;

    public static Fin<ProductAggregate> Create(string name)
    {
        var product = new ProductAggregate();

        // I find this too verbose and looking to simplify:
        if (product.SetName(name) is { IsFail: true } errFin)
        {
            return (Error)errFin;
        }

        return product;
    }

    public Fin<Unit> SetName(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            return Error.New("Product name cannot be null or empty.");
        }

        Name = name;

        return unit;
    }
}

Is there any way I can shorten that up? I really love how Rust does this:

fn get_current_date() -> Result<String, reqwest::Error> {
  let url = "https://postman-echo.com/time/object";
  let res = reqwest::blocking::get(url)?.json::<HashMap<String, i32>>()?;
  let date = res["years"].to_string();
  Ok(date)
}

The ? operator above is chained with further steps, but on itself, it basically check if the left member or call return is an error Result and returns that error then and there. Of course it must match the error type of the enclosing function's return type (reqwest::Error).

Is there a way to achieve something close to as elegant as this, but in C#?

EDIT: Tried to take Mark Seemann's advice about code that should provide a minimal, reproducible example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

分分钟 2025-02-13 21:06:49

您可以将linq语法使用到bind(请参阅eg Leganchext-wiki ):

var result = from p in ProductAggregate.Create()
             from _1 in p.SetName(...)
             from _2 in p.SetCategory(...)
             select p;

这与可能包含“右”值的任何类型一起使用:option尝试 ...

(通过编辑添加:)这是创建的重写

 using static LanguageExt.Prelude;

 public static Fin<ProductAggregate> Create(string name) =>
    from product in FinSucc(new ProductAggregate())
    from _1 in product.SetName(name)
    select product;

You can use LINQ syntax to bind (see e.g. LanguageExt-Wiki):

var result = from p in ProductAggregate.Create()
             from _1 in p.SetName(...)
             from _2 in p.SetCategory(...)
             select p;

This works with any type that maybe contains a "right" value: Option, Either, Try ...

(Added via Edit:) Here's a rewrite of Create

 using static LanguageExt.Prelude;

 public static Fin<ProductAggregate> Create(string name) =>
    from product in FinSucc(new ProductAggregate())
    from _1 in product.SetName(name)
    select product;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文