c# - 定义两个可为 null 的隐式运算符时无法将 null 转换为 struct

标签 c# struct null operator-keyword implicit-conversion

以下不编译:

public struct Foo
{
    public static implicit operator Foo(string bar)
    {
        return new Foo();
    }

    public static implicit operator Foo(long? bar)
    {
        return new Foo();
    }

    public static void Test()
    {
        Foo bar = 0;
        Foo bar2 = (long?)null;
        Foo bar3 = "";
        Foo bar4 = null; // Cannot convert null to 'Foo' because it is a non-nullable value type
    }
}

'Foo bar4 = null' 失败,大概是因为编译器不知道要使用哪个隐式运算符,因为从 long 更改运算符?太长会导致该行编译,但 'Foo bar2 = (long?)null' 会失败(需要显式转换)。

我的问题是;有没有办法让“Foo bar4 = null”也能正常工作,或者这只是语言的限制(我不能添加“null”运算符或告诉它使用哪个来表示 null)?

我意识到我可以将结构更改为一个类,但我不希望它为空,我希望能够让空创建它的一个实例。

编辑: 我应该补充一点,我知道有很多方法可以解决这个问题,但是由于“= null”(本质上执行“new Foo()”)只能使用以下一种方法隐式运算符,我只是想知道是否有可能让它仍然与它们一起工作(我觉得语言中应该有一种方法可以做到这一点 - 现在或将来,不是吗?)。

最佳答案

My question is; Is there a way to make 'Foo bar4 = null' work as well, or is this just a limitation of the language (that I cannot add a 'null' operator or tell it which one to use for null for instance)?

根据这个问题和你的编辑,你基本上是在问

Why does Foo bar4 = null compile when it does not if I add another implicit cast operator?

答案很简单。没有任何上下文的 null 是无类型的,因此编译器不知道要使用哪个运算符。为什么?好吧,支持该语言的重载解析算法不会检查您尝试将 null 分配给的对象的类型,因此它不知道您想要哪个运算符。

您可能会争辩说,可以修改 future 的语言规范来进行这种额外的分析,但团队可能认为这不值得付出努力,否则这将是一个重大变化。

在这种情况下,您能做的最好的事情就是避免强制转换。根据您的 C# 水平,您可以执行以下任一操作:

  • Foo bar4 = default;
  • Foo bar4 = default(Foo);

这会产生可用的 Foo。这两个默认表达式和 new Foo() 都是等价的。它们都会产生一个结构,其所有字段都被清零。

有关更多信息,您可以查看 default value expressions C# 编程指南的部分。

最后,虽然您可以使用将 null 转换为结构的单个隐式转换运算符,但这并不意味着您应该。阅读该代码但不知道类型转换的人可能会质疑他们的理智几分钟。如果可以,最好不要偏离惯用代码。

关于c# - 定义两个可为 null 的隐式运算符时无法将 null 转换为 struct,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52428125/

相关文章:

c# - Owin:多次调用 OnApplyRedirect 并创建不正确的 RedirectUri

c# - 将从 .bin 文件读取的数据解码到字段中

c - 如何将一个数组的变量值赋给另一个变量?

c# - 什么是NullReferenceException,如何解决?

c# - #WT 到底发生了什么?

c# - UWP: MapControl 透明背景

c - 在非结构或 union 中请求成员 'name'

c# - 在 Csharp winform 中将所有空字符串文本框 ("") 设置为空值的简单方法是什么?

arrays - 无法索引到空数组

c# - 为什么 ReSharper 更喜欢 const 而不是 readonly?