'Lifting' C# 函数作为幺半函数失败并更改签名



我试图在c#中编写一个一般的单一性模式,从一个结合两个非空值的齐次函数开始,如果另一个为空,则返回值,或者如果两者都不是,则返回组合值,或为空。这里是:

public static Func<TIn?, TIn?,TIn?> Drop2<TIn>(Func<TIn, TIn, TIn> f)
{
    return (lhs, rhs) =>
    {
        if (lhs == null && rhs == null)
        {
            return default;
        }
        if (lhs == null && rhs != null)
        {
            return rhs;
        }
        if (rhs == null && lhs != null)
        {
            return lhs;
        }
        return f(lhs, rhs);
    };
}

这看起来很好,甚至可以编译,但是当我尝试使用它时,发生了两件奇怪的事情。

    Func<int, int, int> sum = (lhs, rhs) => lhs + rhs;
    var sumNonNull = DropNullable.Drop2(sum);

sumNonNull的智能感知显示为Func<int, int, int>?,而不是预期的Func<int?, int?, int?>,并且我不能将null作为sumNonNull的参数传递(不能从int转换?int)。

这应该工作吗?我错过了什么?

提前感谢您的帮助

我想你需要这样的东西:

    public static Func<TIn?, TIn?, TIn?> Drop2<TIn>(Func<TIn?, TIn?, TIn?> f)
    {
        return (lhs, rhs) =>
              lhs is null ? rhs
            : rhs is null ? lhs
            : f(lhs, rhs);
    }

注意输入参数中的TIn?和结果(它们都可以是null)。然后你可以这样使用:

// note int? - sumInt accepts nulls (int? is a short for Nullable<int>)
Func<int?, int?, int?> sumInt = (a, b) => a + b;
Console.WriteLine(Drop2(sumInt)(null, 123));
Console.WriteLine(Drop2(sumInt)(456, null));
Console.WriteLine(Drop2(sumInt)(456, 123));
Console.WriteLine(Drop2(sumInt)(null, null));
// strings can be null
Func<string, string, string> sumStr = (a, b) => a + b;
Console.WriteLine(Drop2(sumStr)(null, "123"));
Console.WriteLine(Drop2(sumStr)("456", null));
Console.WriteLine(Drop2(sumStr)("456", "123"));
Console.WriteLine(Drop2(sumStr)(null, null));

相关内容

  • 没有找到相关文章

最新更新