gpt4 book ai didi

C# 在红外线 Action 中抛出使其在解析重载时成为 Function

转载 作者:行者123 更新时间:2023-11-30 16:37:13 24 4
gpt4 key购买 nike

我遇到了类型系统的一个非常烦人的极端情况。

我已将代码减少到最低要求以显示问题。

using System;

// Some interface or Base class, doesn't matter
public interface IFace {}
// Some class that implements/extends it
public class Implements: IFace {}

public static class Foo {

public static void Bar<T, T1>(Func<T> f) where T1: IFace {
Console.WriteLine("Bar relaxed");
var _ = f();
}

public static void Bar<T1, T2>(Action f)
where T1: IFace
where T2: IFace
{
Console.WriteLine("Bar strict");
f();
}

public static void Main() {
try {
Bar<Implements, Implements>(() => { // Should call Bar strict
var _ = new Implements();
});

Bar<Implements, Implements>(() => { // Should still call Bar strict
var _ = new Implements();
throw new NullReferenceException(); // But having unconditional throw in the method
// Makes it a `Func<T>` instead of a `Action`
});
} catch(Exception _) {}
}
}

我想要的输出是

Bar strict
Bar strict

我得到的输出是

Bar strict
Bar relaxed

回复:https://repl.it/repls/WearyImpoliteExponent

这可以修复吗? (不删除第一个Bar,或者改变泛型参数个数)

在真实代码中,Bar 方法都没有返回 void,它们返回引用泛型参数的东西,它们的主体也不同

编辑:澄清一下,“真实世界”Bar 方法看起来更像这样:

public static Baz<T, IFace> Bar<T, T1>(Func<T> f) where T1: IFace;

public static Baz<Default, IFace> Bar<T1, T2>(Action f)
where T1: IFace
where T2: IFace;

// Where `Default` is a concrete type
struct Default {}

“真实世界”代码:https://repl.it/repls/NaturalNoisyOpensoundsystem

最佳答案

是的,你可以做到这一点。诀窍是在抛出的异常之后添加一个return;

Foo.Bar<Implements, Implements>(() =>
{ // Should still call Bar strict
var _ = new Implements();
throw new NullReferenceException();
return;
}

lambda 现在将正确解析为 Action 而不是 Func

发生这种情况的原因是重载解析如何工作的一个非常奇怪的极端情况。本质上,如果一个 lambda 表达式可以被认为是一个 Func,它总是比 Action 更受欢迎。只要所有代码路径都返回与您预期的返回类型兼容的内容,就会选择 Func 重载。由于您的返回为零,因此满足此条件,并使用 Func 重载。

关于C# 在红外线 Action 中抛出使其在解析重载时成为 Function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59052451/

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