【发布时间】:2020-01-14 17:47:20
【问题描述】:
在 C# 中使用新的可为空引用类型。很高兴看到他们从斯威夫特那里挖走了这个!这是一个很棒的功能!但是......因为它本质上是语言的“固定”,我正在努力创建一个可以采用任何可空类型(无论是值还是引用)的泛型,这在 Swift 中是微不足道的。
考虑这个类:
public abstract class LabeledValue<TValue> {
public string? label { get; set; }
public TValue? value { get; set; }
}
这是我想要实现的目标,以 Int 和一个名为 'Foo' 的类为例:
public class LabeledInt : LabeledValue<Int>{}
var myLabeledIntA = new LabeledInt(){
label = "Forty Four",
value = 44
}
var myLabeledIntB = new LabeledInt(){
label = "Not Set",
value = null
}
public class LabeledFoo : LabeledValue<Foo>{}
var myLabeledFooA = new LabeledFoo(){
label = "Set",
value = new Foo()
}
var myLabeledFooB = new LabeledFoo(){
label = "Not Set",
value = null
}
这抱怨我必须将 TValue 定义为可为空的。但是,我找不到可以同时解决可空值类型(即 Int?)和可空引用类型(即 Foo?)的约束。这样的约束怎么写?
这些都行不通...
public abstract class LabeledValue<TValue>
where TValue : Nullable {
public string? label { get; set; }
public TValue? value { get; set; }
}
public abstract class LabeledValue<TValue>
where TValue : struct {
public string? label { get; set; }
public TValue? value { get; set; }
}
public abstract class LabeledValue<TValue> {
public string? label { get; set; }
public Nullable<TValue> value { get; set; }
}
注意,我也尝试过这个想法,认为可空性可以作为实际类型参数传入,但随后它抱怨“值”未设置。
public abstract class LabeledValue<TValue> {
public string? label { get; set; }
public TValue value { get; set; }
}
public class LabeledInt : LabeledValue<Int?>{}
【问题讨论】:
-
您是否尝试在此处搜索现有答案?
Nullable<T>是结构和值类型,可空引用显然是引用类型。您应该使用class或struct通用约束,就像在article 中的issue with T?部分中解释的那样@ -
如果你看上面,我试过了(最后一个答案在第二个到最后一个代码块。)是的,我在这里搜索过。当我没有找到任何可以回答这个问题的东西时,这就是我发布这个问题的原因。如果您知道解决方案,请随时在此处将其作为答案发布,如果有效,我将予以标记。
-
你至少可以看看这个thread
-
TValue?当TValue: class和TValue: struct从CLR 的角度来看是完全不同的东西时,可空引用类型使用属性进行注释,可空值类型是Nullable<T>类型。你应该自己考虑,在这种情况下你想要什么。或者用前置条件和后置条件属性装饰类型 -
是的,我刚刚发布了一个答案。惭愧,但我理解,因为它们被附加到 C# 上,而它们从一开始就是 Swift 的基本组成部分。在 Swift 中,无论 T 是类还是结构,可空变量都是具体的
Optional<T>,因此它们是相同的类型,因此是允许的。
标签: c# generics nullable nullable-reference-types