【问题标题】:Distinguish an explicitly nullable string type in C# [duplicate]在 C# 中区分显式可为空的字符串类型 [重复]
【发布时间】: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&lt;MyClass&gt; myClass {get;set;}。这 ?值类型和引用类型的语法不同。
  • 稍微查看 IL 代码后,编译器似乎不会将 string? 解释为 Nullable&lt;string&gt;,而是将其视为普通的 string 和 @987654342 @ 在属性/字段上,NullableContextAttribute 在 getter 和 setter 上。这两个属性都采用2 的参数,表示可以为空。 1 表示不可为空。

标签: c#


【解决方案1】:

@Jesse 让我指出了正确的方向。如果有人稍后再看,这就是我最终检查的方式,它似乎正在全面发挥作用:

if(modelProperty.PropertyType == typeof(string)
&& modelProperty.GetMethod?.CustomAttributes.Where(x => x.AttributeType.Name == "NullableContextAttribute").Count() == 0){
    nullable = true;
}

仍然很高兴接受更简洁的答案!

【讨论】:

    猜你喜欢
    • 2019-05-31
    • 1970-01-01
    • 2012-06-21
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多