gpt4 book ai didi

c# - iSynaptic.Commons 和 Maybe Monad

转载 作者:行者123 更新时间:2023-11-30 12:34:13 26 4
gpt4 key购买 nike

我一直在努力弄清楚如何在 iSynaptic.Commons 中使用 Maybe monad在我的值检索器可能抛出异常的上下文中:

例如:

dynamic expando = new Expando();
expando.Name = "John Doe";

var maybe = Maybe.Defer(()=>(string)expando.NonExistingProperty);

//In this context I would like the exception which is thrown
//to result in Maybe<string>.NoValue;
if(maybe.HasValue) {
//Do something
}

这有可能实现吗?

最佳答案

有几种使用 iSynaptic.Commons 允许异常的方法。我发现的每种方法都需要 .Catch() 扩展方法来让 monad 知道静默捕获异常。另外,访问属性 maybe.Value 时要小心。如果此属性为 Maybe.NoValue,将抛出 InvalidOperationException。


1) 创建一个“OnExceptionNoValue”扩展方法。这将检查 Maybe 以查看它是否有异常。如果是,则返回 NoValue Maybe。否则原始的 Maybe 将被退回。

public static class MaybeLocalExtensions
{
public static Maybe<T> OnExceptionNoValue<T>(this Maybe<T> maybe)
{
return maybe.Exception != null ? Maybe<T>.NoValue : maybe;
}
}

// Sample Use Case:
var maybe = Maybe.Defer(() => (string)expando.NonExistingProperty).Catch()
.OnExceptionNoValue();

2) 创建一个“BindCatch”扩展方法。这会在出现异常时更改正常绑定(bind)的行为以返回 Maybe.NoValue 而不是抛出异常。

public static class MaybeLocalExtensions
{
public static Maybe<TResult> BindCatch<T, TResult>(this Maybe<T> @this, Func<T, Maybe<TResult>> selector)
{
var self = @this;

return new Maybe<TResult>(() => {
if (self.Exception != null)
return Maybe<TResult>.NoValue;

return self.HasValue ? selector(self.Value) : Maybe<TResult>.NoValue;
});
}
}

// Sample Use Case:
var maybe = Maybe.Defer(() => (string)expando.NonExistingProperty).Catch()
.BindCatch(m => m.ToMaybe());

3) 这种方式也使用了 Catch() 扩展方法,但是使用了 maybe.HasValue 属性,而不是依赖于扩展方法。如果 Maybe 中存在异常,则 HasValue 属性为 false。当此值为 false 时,Maybe.NoValue 可以替换变量的值 maybe 或在这种情况下需要做的任何事情。

dynamic expando = new ExpandoObject();
expando.Name = "John Doe";

// This example falls to the else block.
var maybe = Maybe.Defer(() => (string)expando.NonExistingProperty).Catch();

//In this context I would like the exception which is thrown
//to result in Maybe<string>.NoValue;
if (maybe.HasValue) {
//Do something
Console.WriteLine(maybe.Value);
} else {
maybe = Maybe<string>.NoValue; // This line is run
}

// This example uses the if block.
maybe = Maybe.Defer(() => (string)expando.Name).Catch();
//to result in Maybe<string>.NoValue;
if (maybe.HasValue) {
//Do something
Console.WriteLine(maybe.Value); //This line is run
} else {
maybe = Maybe<string>.NoValue;
}

这些答案都是同一主题的变体,但我希望它们对您有所帮助。

关于c# - iSynaptic.Commons 和 Maybe Monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7654138/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com