关于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