如何使泛型参数T在C#中为空?

如何使泛型参数T在C#中为空?,c#,generics,C#,Generics,我正在创建一个通用方法,它应该能够返回null public T? GetSecondSmallest<T>(List<T> items) where T : Nullable, IComparable { if (items.Count == 0) return null; T smallest = items[0]; T? secondSmallest = null; // Find second smallest by loopi

我正在创建一个通用方法,它应该能够返回
null

public T? GetSecondSmallest<T>(List<T> items) where T : Nullable, IComparable
{
    if (items.Count == 0) return null;

    T smallest = items[0];
    T? secondSmallest = null;

    // Find second smallest by looping through list

    return secondSmallest;
}
例如,我在下面创建了这个方法
getsecondminister(List)
。此函数循环遍历所有
i可比较的
项,并尽可能返回第二个最小的项。如果此项不存在,则返回
null

public T? GetSecondSmallest<T>(List<T> items) where T : Nullable, IComparable
{
    if (items.Count == 0) return null;

    T smallest = items[0];
    T? secondSmallest = null;

    // Find second smallest by looping through list

    return secondSmallest;
}
公共电话?GetSecondMinister(列表项),其中T:Nullable,IComparable { if(items.Count==0)返回null; T=项目[0]; T?最小值=零; //通过循环列表找到第二个最小的 返回最小值; } 此方法的两个示例用法为:

GetSecondSmallest(new List<int> {4, 2, 3, 1, 6, 8}) // Should return 2
GetSecondSmallest(new List<MyComparable> {new MyComparable('x')}) // Should return null
getSecondMinister(新列表{4,2,3,1,6,8})//应该返回2
GetSecondMinister(新列表{new MyComparable('x')})//应返回null
当您尝试编译此代码时,您将看到这里的问题:

错误CS0717可为空:静态类不能用作约束

如何使此方法返回
T
null
的实例



编辑:我已经看到了,但这并不能回答我的问题,因为在我的情况下,参数也是泛型的,应该是
可为空的
。因此这里提供的答案不适用。

将返回类型更改为Nullable,并使用non-Nullable参数调用该方法

简单的例子:

static void Main(string[] args)
{
    int? i = GetValueOrNull<int>(null, string.Empty);
}


public static Nullable<T> GetValueOrNull<T>(DbDataRecord reader, string columnName) where T : struct
{
    object columnValue = reader[columnName];

    if (!(columnValue is DBNull))
        return (T)columnValue;

    return null;
}
static void Main(字符串[]args)
{
int?i=GetValueOrNull(null,string.Empty);
}
公共静态可空GetValueOrNull(DbDataRecord读取器,字符串columnName),其中T:struct
{
对象columnValue=读卡器[columnName];
如果(!(columnValue为DBNull))
返回(T)列值;
返回null;
}

UPD

像这样:

public Nullable<T> GetSecondSmallest<T>(List<T> items) where T : IComparable
{
    if (items.Count == 0) return null;

    Nullable<T> smallest = items[0];
    Nullable<T> secondSmallest = null;

    // Find second smallest by looping through list

    return secondSmallest;
}
public可空getsecondminister(列表项),其中T:IComparable
{
if(items.Count==0)返回null;
可为空的最小项=项[0];
可空=空;
//通过循环列表找到第二个最小的
返回最小值;
}

您不能将
t
缩小为可空或对象。您必须创建两种方法,一种用于
T
,另一种用于
T?

public T? GetSecondSmallestAsNullable<T>(List<T> items) where T : struct
{
    return null;
}

public T GetSecondSmallestAsClass<T>(List<T> items) where T : class
{
    return null;
}
公共电话?GetSecondSmallestAsNullable(列表项),其中T:struct { 返回null; } 公共T GetSecondSmallestAsClass(列表项),其中T:class { 返回null; }
使用诸如Tuple之类的包装类来包装结果值。在下面的示例中,如果没有第二小项,则返回null,否则返回具有第二小值的元组

public static void Main()
{
    var result1 = GetSecondSmallest(new List<int>
    {
    4, 2, 3, 1, 6, 8
    }); // Should return 2

    var result2 = GetSecondSmallest(new List<MyComparable>
    {
    new MyComparable('x')
    }); // Should return null

    Console.WriteLine("result1=" + result1.Item1);
    Console.WriteLine("result2 == null: " + (result2 == null));
}

public static Tuple<T> GetSecondSmallest<T>(List<T> items)where T : IComparable
{
    return items.Skip(1).Select(v => Tuple.Create(v)).FirstOrDefault();
}
publicstaticvoidmain()
{
var result1=GetSecondMinister(新列表
{
4, 2, 3, 1, 6, 8
});//应该返回2
var result2=getSecondMinister(新列表
{
新的MyComparable('x')
});//应返回null
Console.WriteLine(“result1=“+result1.Item1”);
WriteLine(“result2==null:+(result2==null));
}
公共静态元组GetSecondMinister(列表项),其中T:IComparable
{
returnitems.Skip(1).选择(v=>Tuple.Create(v)).FirstOrDefault();
}

@j0ey\u wh
不可下载的
界面设计用于数据库。它不是一个
Nullable
实现的接口。您是否尝试过我的第二个示例用法?它不适用于此解决方案,因为它现在要求t不可为空,所以基本上重复代码是这里的最佳解决方案?必须有更好的方法重写.NET framework以更好地支持泛型为nullable?另一种方法可以是使用in C#(作为包装泛型)向调用方指示谓词上没有匹配项。这将消除struct v类与可空类型之间的两难关系。然而,它确实需要对代码进行重大重构/引入FP框架代码。