C# Type 字符串的种类?是 TypeKind.Class
C# TypeKind of string? is TypeKind.Class
改写问题:
我有这个 equalitycomparer 与 Generic type constrained to a class
public class ReferenceEqualityComparer<T> : IEqualityComparer<T> where T : class
{
public static ReferenceEqualityComparer<T> Default => new();
public bool Equals(T? x, T? y) => ReferenceEquals(x, y);
public int GetHashCode(T? obj) => RuntimeHelpers.GetHashCode(obj);
}
当 class 假设
public class A
{
public string? P1{get; set;}
}
被代码生成器消耗
[Generator]
public class MyCodeGenerator : ISourceGenerator
{
}
NetAnalyzer 表示 string?
的 TypeKind 为 class
但是当我这样做时,
#nullable enable
[TestMethod]
public void RefTest()
{
string? s1 = "adsad";
string? s3 = s1;
Assert.IsTrue(ReferenceEqualityComparer<string?>.Default.Equals(s1, s3));
}
#nullable restore
它说 string?
不匹配 'class' 约束。即使分析器告诉我它是 class,我是否遗漏了什么?还是我误解了这个概念?
原问题:根据微软文档Nullable的描述,他们class化为structs
,但为什么是CodeAnalyzer 告诉我 string?
的 TypeKind 是 TypeKind.Class?
这里有一些上下文,在我正在编写的库中,classes 被分析用于源代码生成(C# 9 源代码生成器),它本质上是使用 .NetAnalyzer。 class 的每个属性都将检查它们的类型是否被视为 class。结果 string?
被认为是 Class.
string
s are classes and cannot be used as generic type argument for Nullable
because of the generic constraint where T : struct
. In your context string?
is a nullable reference type,可用于向编译器指示引用类型不应将 null
作为值(变量仍然可以将 null
作为值并应进行检查对于 public API 中的 null
值,但当您在不可空上下文中使用 null
时编译器会警告您)
There is C# 中可空 类 的特定约束,因此从编译时约束的角度来看 SomeRefType?
不匹配 T:class
,但会匹配 T:class?
.
where T : class
The type argument must be a reference type. This constraint applies also to any class, interface, delegate, or array type. In a nullable context in C# 8.0 or later, T must be a non-nullable reference type.
where T : class?
The type argument must be a reference type, either nullable or non-nullable. This constraint applies also to any class, interface, delegate, or array type.
所以可能在可为 null 的上下文中你会想要使用第二个:
public class ReferenceEqualityComparer<T> : IEqualityComparer<T> where T : class?
不会对 string?
和 string
发出任何警告。
改写问题:
我有这个 equalitycomparer 与 Generic type constrained to a class
public class ReferenceEqualityComparer<T> : IEqualityComparer<T> where T : class
{
public static ReferenceEqualityComparer<T> Default => new();
public bool Equals(T? x, T? y) => ReferenceEquals(x, y);
public int GetHashCode(T? obj) => RuntimeHelpers.GetHashCode(obj);
}
当 class 假设
public class A
{
public string? P1{get; set;}
}
被代码生成器消耗
[Generator]
public class MyCodeGenerator : ISourceGenerator
{
}
NetAnalyzer 表示 string?
的 TypeKind 为 class
但是当我这样做时,
#nullable enable
[TestMethod]
public void RefTest()
{
string? s1 = "adsad";
string? s3 = s1;
Assert.IsTrue(ReferenceEqualityComparer<string?>.Default.Equals(s1, s3));
}
#nullable restore
它说 string?
不匹配 'class' 约束。即使分析器告诉我它是 class,我是否遗漏了什么?还是我误解了这个概念?
原问题:根据微软文档Nullable的描述,他们class化为structs
,但为什么是CodeAnalyzer 告诉我 string?
的 TypeKind 是 TypeKind.Class?
这里有一些上下文,在我正在编写的库中,classes 被分析用于源代码生成(C# 9 源代码生成器),它本质上是使用 .NetAnalyzer。 class 的每个属性都将检查它们的类型是否被视为 class。结果 string?
被认为是 Class.
string
s are classes and cannot be used as generic type argument for Nullable
because of the generic constraint where T : struct
. In your context string?
is a nullable reference type,可用于向编译器指示引用类型不应将 null
作为值(变量仍然可以将 null
作为值并应进行检查对于 public API 中的 null
值,但当您在不可空上下文中使用 null
时编译器会警告您)
There is C# 中可空 类 的特定约束,因此从编译时约束的角度来看 SomeRefType?
不匹配 T:class
,但会匹配 T:class?
.
where T : class
The type argument must be a reference type. This constraint applies also to any class, interface, delegate, or array type. In a nullable context in C# 8.0 or later, T must be a non-nullable reference type.
where T : class?
The type argument must be a reference type, either nullable or non-nullable. This constraint applies also to any class, interface, delegate, or array type.
所以可能在可为 null 的上下文中你会想要使用第二个:
public class ReferenceEqualityComparer<T> : IEqualityComparer<T> where T : class?
不会对 string?
和 string
发出任何警告。