正如你所说,这与MessageBox
无关,而取决于ToString()
方法的实现。
例如,看一下System.Runtime
中的struct Nullable<T> where T : struct
,其中包含一个可空枚举的示例:
[Serializable]
[NonVersionable] // This only applies to field layout
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public partial struct Nullable<T> where T : struct
在 .NET 7 中,ToString()
的实现看起来像这样:
public override string? ToString() => hasValue ? value.ToString() : ""
因此,即使在null对象
tc.TestEnum
的
ToString()
上调用,以下代码在
MessageBox.Show(s.ToString());
引发异常。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var tc = new TestClass();
MessageBox.Show(tc.TestEnum.ToString());
string s = null;
MessageBox.Show(s);
MessageBox.Show(s.ToString());
}
}
public enum TestEnum
{
None = 0
}
public class TestClass
{
public TestEnum? TestEnum { get; set; }
}
System.NullReferenceException:“对象引用未设置为对象的实例。”
![enter image description here](https://istack.dev59.com/PKbAN.webp)
从 System.Runtime
中查看 class String
:
[Serializable]
[NonVersionable] // This only applies to field layout
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public sealed partial class String : IComparable, IEnumerable, IConvertible, IEnumerable<char>, IComparable<string?>, IEquatable<string?>, ICloneable
这里我们有另一个实现,它会抛出你看到的错误:
public override string ToString()
{
return this;
}
然而,从 .NET 6<
开始,<Nullable>enable</Nullable>
对于新项目默认启用。
https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references
上面的代码将会给你两个警告:
string s = null;
-> CS8600 将 null 文本或可能为 null 的值转换为非可空类型。
MessageBox.Show(s.ToString());
-> CS8602 可能为 null 的引用的解除引用。
![enter image description here](https://istack.dev59.com/DXBo5.webp)
按照以下方式重写代码,错误将消失:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var tc = new TestClass();
MessageBox.Show(tc.TestEnum.ToString());
string? s = null;
MessageBox.Show(s);
if (s is not null)
{
MessageBox.Show(s.ToString());
}
}
}
public enum TestEnum
{
None = 0
}
public class TestClass
{
public TestEnum? TestEnum { get; set; }
}
或者简单地使用空值条件运算符?.
,就像@mr R所写的那样:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var tc = new TestClass();
MessageBox.Show(tc.TestEnum.ToString());
string? s = null;
MessageBox.Show(s);
MessageBox.Show(s?.ToString());
}
}
public enum TestEnum
{
None = 0
}
public class TestClass
{
public TestEnum? TestEnum { get; set; }
}
null
损坏,可以使用obj?.ToString() ?? ""
。 - bvj