【发布时间】:2020-06-18 21:34:04
【问题描述】:
我有两个类——一个内部类和一个外部类,其中内部类可以返回一个空值和一个不应该返回空值的外部类(当然,假设类型参数 T 代表一个非可空类型):
#nullable enable
public class Insider<T>
{
[MaybeNull, AllowNull]
public T Value {get; set; }
public Insider()
{ Value = default; }
}
public class Outsider<T>
{
Insider<T> Inside = new Insider<T>();
public T Value
{
get
{
return Inside.Value; // Compiler warning "'Value' may be null here"
}
set { Inside.Value = value; }
}
}
public class Fred
{ }
public static class Test
{
public static void Stuff()
{
Outsider<Fred> one = new Outsider<Fred>();
Debug.WriteLine("one.Value is " + one.Value);
Outsider<Fred?> two = new Outsider<Fred?>();
Debug.WriteLine("two.Value is " + two.Value);
Outsider<int> three = new Outsider<int>();
Debug.WriteLine("three.Value is " + three.Value);
}
}
#nullable disable
当我运行它时,它会给出预期的输出:
one.Value is
two.Value is
three.Value is 0
导致“Insider.Value”为空的程序状态是一种特定的错误状态,调用者应该知道系统处于该状态而不访问“Outsider.Value”,这意味着调用者永远不会看到“ Outsider.Value" 返回 null,但我想强制执行。
是的,两个类都应该处理结构和类。
我当时的想法是这样的:
public class Outsider<T>
{
Insider<T> Inside = new Insider<T>();
public T Value
{
get
{
if ((Inside.Value == null)&&(T_shouldnt_be_null))
throw new Exception("Nope");
return Inside.Value;
}
set { Inside.Value = value; }
}
}
当然,麻烦的部分是“T_shouldnt_be_null”。
如果我在 Outsider.Value 中进行更多调试:
public class Outsider<T>
{
Insider<T> Inside = new Insider<T>();
public T Value
{
get
{
Type? nullableType = Nullable.GetUnderlyingType(typeof(T));
Debug.WriteLine(" typeof(T) is " + typeof(T) + "; nullableType=" + ((nullableType==null)?"null": nullableType.ToString()));
foreach (var x in typeof(T).CustomAttributes)
Debug.WriteLine(" " + x);
return Inside.Value;
}
set { Inside.Value = value; }
}
}
我得到的结果不是我所期望的。当类型参数 T 为 Fred(不可为空)时的结果是:
typeof(T) is BTSDataCollator.Fred; nullableType=null
当type参数是Fred时的结果呢? (可为空)是:
typeof(T) is BTSDataCollator.Fred; nullableType=null
编译器已经从类型中完全去除了可空性指示符。在这两种情况下,类类型都没有 CustomAttributes(这就是 this post 用来确定可空性的依据)
(通用)类有什么方法可以获取有关其实际类型参数的可空性的信息(Fred 与 Fred?)?
【问题讨论】:
-
Nullable.GetUnderlyingType用于可空值类型。 -
您不能在编译时确保局外人的 T 不可为空吗? “公共类局外人
where T: struct”。在这种情况下,如果您尝试使用引用类型(可为空),则会出现编译器错误。 -
唉,正如我在帖子中所说,“两个类都应该处理结构和类。”
-
@GuruStron 我正在尝试一切我能想到的“看到”可空性。我预计当我实例化 Outsider
时,T 会是 Nullable ,但事实并非如此。 -
@PavelAnikhouski 唉,我已经打印出 typeof(T) 的 CustomAttributes 以及 Outsider 的 Value 属性的 CustomAttributes 和 Outsider 的 Value 属性的 PropertyType 的 CustomAttributes。在每种情况下都有 -zero- CustomAttributes,这是 StackOverflow 帖子所依赖的
标签: c# reflection nullable c#-8.0 nullable-reference-types