【发布时间】:2022-01-29 16:28:09
【问题描述】:
有很多带有“可空”和“不可空”声明的字符串属性示例:
public MyClass {
public string NotNullable {get;set;}
public string? Nullable {get;set;}
}
这甚至在 Microsoft C# official documentation on nullables 中显示为可空类型的主要示例。
C# 中的字符串在默认情况下可以为空,这使这一事实变得令人困惑。
string myString = null; //100% valid, compile-able code
我有一个脚本,我在其中检查类中的属性类型,以查看它们是否可以为空。这是一个很长的故事,但是这些可以为空的标志被放在一个列表中并导出。
bool nullable = false;
if (classProperty.PropertyType.IsGenericType
&& classProperty.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
nullable = true;
}
这适用于int?s、类引用、DateTime? 对象,基本上是string? 以外的任何东西,它可以确定它是否是显式声明的可空属性。
有什么方法可以确定一个属性是 string 还是 string?,如果不是,为什么(并在文档中称赞)C# 的可空字符串类型?
也试过了
另一种方法,将PropertyType 与直接派生的类型进行比较:
modelProperty.PropertyType == typeof(int) //works
modelProperty.PropertyType == typeof(int?) //works
modelProperty.PropertyType == typeof(double) //works
modelProperty.PropertyType == typeof(double?) //works
modelProperty.PropertyType == typeof(string) //works
modelProperty.PropertyType == typeof(string?) //NOPE!
C# 在传递 string? 时会吐出一个错误,即无法在可空类型上使用 typeof 运算符,尽管对于 int? 和 double? 确实这样做没有问题。此外,modelProperty == typeof(string) 为真,无论该属性是使用 string 还是 string? 声明的。
【问题讨论】:
-
不是一个完整的答案,但 int 是一个值类型。 DateTime 是一个结构。 string 很特殊,它是不可变值的引用类型。你也不能有一个可以为空的类引用,比如
public Nullable<MyClass> myClass {get;set;}。这 ?值类型和引用类型的语法不同。 -
稍微查看 IL 代码后,编译器似乎不会将
string?解释为Nullable<string>,而是将其视为普通的string和 @987654342 @ 在属性/字段上,NullableContextAttribute在 getter 和 setter 上。这两个属性都采用2的参数,表示可以为空。1表示不可为空。
标签: c#