关于C#泛型参数的Nullable
About Nullable of C# generic parameter
现在我有一个 SomeClass<T>
和一个构造函数 SomeClass(IList<T?> list)
。但是当我使用 List<int?>
构造它时,编译器告诉我:
Cannot resolve constructor
SomeClass(System.Collections.Generic.List<System.Nullable<int>>)
,
candidates are: SomeClass(System.Collections.Generic.IList<int>)
我发现这意味着我必须将“struct”添加到 T 的基础 class 列表中以确保 T 是一个值类型,但为什么会发生这种情况以及如何使这个 class 避免只使用值类型作为泛型参数?
@canton7 在评论中解释了为什么这不起作用。
你不能用构造函数解决这个问题,因为你必须引入一个新的类型参数,而构造函数不能声明类型参数。因此我建议使用工厂方法。
public class SomeClass<T>
{
public IList<T> List { get; private set; }
public static SomeClass<T> Create<U>(IList<Nullable<U>> list)
where U : struct, T
{
return new SomeClass<T> {
List = list
.OfType<T>()
.ToList()
};
}
}
引入类型参数U
允许我们添加一个类型约束,限制在这个方法中,而class的类型参数T
保持不受约束。
请注意,null
值没有类型。因此,OfType<T>()
过滤掉空值。
你可以这样测试:
var ints = new List<int?> { 1, 2, null, 3 };
var sut = SomeClass<int>.Create(ints);
foreach (int item in sut.List) {
Console.WriteLine(item);
}
打印:
1
2
3
现在我有一个 SomeClass<T>
和一个构造函数 SomeClass(IList<T?> list)
。但是当我使用 List<int?>
构造它时,编译器告诉我:
Cannot resolve constructor
SomeClass(System.Collections.Generic.List<System.Nullable<int>>)
, candidates are:SomeClass(System.Collections.Generic.IList<int>)
我发现这意味着我必须将“struct”添加到 T 的基础 class 列表中以确保 T 是一个值类型,但为什么会发生这种情况以及如何使这个 class 避免只使用值类型作为泛型参数?
@canton7 在评论中解释了为什么这不起作用。
你不能用构造函数解决这个问题,因为你必须引入一个新的类型参数,而构造函数不能声明类型参数。因此我建议使用工厂方法。
public class SomeClass<T>
{
public IList<T> List { get; private set; }
public static SomeClass<T> Create<U>(IList<Nullable<U>> list)
where U : struct, T
{
return new SomeClass<T> {
List = list
.OfType<T>()
.ToList()
};
}
}
引入类型参数U
允许我们添加一个类型约束,限制在这个方法中,而class的类型参数T
保持不受约束。
请注意,null
值没有类型。因此,OfType<T>()
过滤掉空值。
你可以这样测试:
var ints = new List<int?> { 1, 2, null, 3 };
var sut = SomeClass<int>.Create(ints);
foreach (int item in sut.List) {
Console.WriteLine(item);
}
打印:
1
2
3