- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
编辑:在给我模式等选项之前,请参阅下面我对 C#8.0 中 Null 的立场的更新
原始问题
我正在尝试将我的基础库升级为“启用空”,也就是使用 C# 8.0 <Nullable>enable</Nullable>
旗帜。
在尝试使用抽象和特定泛型时,我遇到了一些问题。考虑以下代码片段,它接受 Action
。并将其转换为 Func<TResult>
.这是pre-nullable-enable:
public static Func<TResult> ToFunc<TResult>(this Action action)
=> () => { action(); return default; }
;
但是 post-nullable-enable 我似乎很挣扎,因为我不能让 TResult 可以为空(或 TResult?
),因为机智需要 where TResult: class
的约束或 where TResult: struct
.我无法将这两个约束结合起来让编译器知道 TResult 可以是类或值类型。目前我觉得这很烦人 - 因为人们应该能够表达无论是类还是结构,它都可以为空(无论以前的 .NET 继承设计如何)。
所以,post-nullable-enable我似乎只有一个选择,那就是代码重复,例子如下:
public static Func<TResult?> ToFuncClass<TResult>(this Action action)
where TResult : class
=> () => { action(); return null; }
;
public static Func<TResult?> ToFuncStruct<TResult>(this Action action)
where TResult : struct
=> () => { action(); return null; }
;
代码重复以及随之而来的命名方案都让我很困扰。我可能误解了正确的用法,或者我可能遗漏了规范的另一个功能,但您将如何解决这个问题?
更新:事实上,我认为我宁愿坚持使用我自己的“空处理”实现,也不愿使用 C#8.0 的可空特性。作为一个“空”对象或充实的“选项/可能/无”-解决方案似乎可以更好地传达信息。我唯一担心的是它在插入语言发展、培训新编码员和引入另一个方面不是很有帮助>第三方/非本地解决方案到普遍问题我们都处理空值。因为自己的 null 处理实现 非常棒,但是在每个代码库中出现不同,需要由社区维护,并且您有各种不同的风格。因此,如果语言完全强制执行它,并且标准上升,那将是非常有帮助和非常有益的。我希望这会是 - 显然不是,我理解。但我觉得这是一个错失的机会。
谢谢伊夫
最佳答案
原因在Try out Nullable Reference Types中解释在 The issue with T?
部分.本质上,没有办法解决这个问题。
首先,什么是T
当我们使用 T?
?它是可为空的还是不可为空的?
A natural definition of T? would mean, "any nullable type". However, this would imply that T would mean "any non-nullable type", and that is not true! It is possible to substitute a T with a nullable value type today (such as bool?).
其次,每种情况下使用的类型不同 - a string?
仍然是string
同时 int?
是 Nullable<int>
.在每种情况下生成的具体方法 是完全不同的。在一种情况下,您会得到一个
Func<string> ToFuncClass<string>(this Action action)
在另一个方面,你得到一个
Func<Nullable<int>> ToFuncStruct<int>(this Action)
Next, it’s important to note that a nullable reference type is not the same thing as a nullable value type. Nullable value types map to a concrete class type in .NET. So int? is actually Nullable. But for string?, it’s actually the same string but with a compiler-generated attribute annotating it. This is done for backwards compatibility. In other words, string? is kind of a "fake type", whereas int? is not.
文章的示例演示了这一点:
This distinction between nullable value types and nullable reference types comes up in a pattern such as this:
void M<T>(T? t) where T: notnull
This would mean that the parameter is the nullable version of T, and T is constrained to be notnull.
If T were a string, then the actual signature of M would be :
M<string>([NullableAttribute] T t)
but if T were an int, then M would be
M<int>(Nullable<int> t)
These two signatures are fundamentally different, and this difference is not reconcilable.
关于c# - 泛型和可空(类与结构),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58317700/
我是一名优秀的程序员,十分优秀!