为什么不能在c#中将null转换为类型参数T?

Rob*_*ien 4 c# vb.net vb.net-to-c#

我正在将一堆代码从VB转换为C#,而我正在遇到一个方法的问题.这个VB方法效果很好:

Public Function FindItem(ByVal p_propertyName As String, ByVal p_value As Object) As T

    Dim index As Int32

    index = FindIndex(p_propertyName, p_value)

    If index >= 0 Then
        Return Me(index)
    End If

    Return Nothing

End Function
Run Code Online (Sandbox Code Playgroud)

它允许为T返回Nothing(null)

C#等价物不起作用:

public T FindItem(string p_propertyName, object p_value)
{
  Int32 index = FindIndex(p_propertyName, p_value);

  if (index >= 0) {
    return this[index];
  }
  return null;
}
Run Code Online (Sandbox Code Playgroud)

它不会使用此错误进行编译:

类型'T'必须是不可为空的值类型,以便在泛型类型或方法中将其用作参数'T' 'System.Nullable<T>'

我需要能够具有相同的功能,否则会破坏很多代码.我错过了什么?

cuo*_*gle 12

由于T可以是引用类型或值类型,因此null如果T是值类型,则返回将不满足.你应该回来:

return default(T);
Run Code Online (Sandbox Code Playgroud)

从链接默认关键字:

给定参数化类型T的变量t,语句t = null仅在T是引用类型时有效,并且t = 0仅适用于数值类型而不适用于结构.解决方案是使用default关键字,它将为引用类型返回null,为数值类型返回零.对于结构体,它将返回初始化为struct或null的结构的每个成员,具体取决于它们是值还是引用类型.对于可空值类型,default返回一个System.Nullable,它像任何结构一样初始化.

  • @RobertBeaubien:如果T是引用类型,`default(T)`将返回`null`,请检查链接. (3认同)
  • @RobertBeaubien:如果你真的想要返回`null`,你需要通过使用`where T:class`来约束T是引用类型,但你应该注意到如果T是值类型,这种方式将不起作用 (2认同)
  • @RobertBeaubien VB.Net的"Nothing"等同于C#的`default()`,而不是`null`.https://msdn.microsoft.com/en-us/library/0x9tb07z.aspx (2认同)
  • VB关键字"Nothing"在C#中拼写为"default(T)".在所有情况下,他们都做同样的事情.(另请注意,Null与Null不同.所有Null都没有,但并非所有Null都是Null.) (2认同)