首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么不能在c#中将null转换为类型参数T?

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

Stack Overflow用户
提问于 2015-01-25 04:23:15
回答 3查看 12.7K关注 0票数 11

我正在将一堆代码从VB转换到C#,我正在处理一个方法的问题。这个VB方法工作得很好:

代码语言:javascript
运行
复制
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

它允许对T返回空(空)。

C#等价物不起作用:

代码语言:javascript
运行
复制
public T FindItem(string p_propertyName, object p_value)
{
  Int32 index = FindIndex(p_propertyName, p_value);

  if (index >= 0) {
    return this[index];
  }
  return null;
}

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

类型'T‘必须是非空值类型,才能将其用作泛型类型或方法'System.Nullable<T>'中的参数'T’。

我需要能够拥有相同的功能,否则它会破坏很多代码。我遗漏了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-25 04:34:48

因为T可以是引用类型,也可以是值类型,所以如果T是值类型,返回null就不能满足。你应该返回:

代码语言:javascript
运行
复制
return default(T);

从链接默认关键字

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

更新(2021-09-27)

使用C# 7.1中的新语法,您可以返回:

代码语言:javascript
运行
复制
return default;
票数 44
EN

Stack Overflow用户

发布于 2015-01-25 04:56:59

对于C#,您必须使用默认(T),如果只返回T而不返回T,则它将返回0而不是零或空。

现在,在VB.net的情况下,如您的示例所示,您说不返回任何内容,这是正确的,但是您是否试图检查该函数的返回值。

喜欢

代码语言:javascript
运行
复制
Dim c = <<your class object>>.FindItem("test",Nothing);  // you have to pass valid values.

如果您检查C的值,那么它是0,而不是零。

现在到了MSIL级别所发生的事情。

当您编译VB.net代码并检查其MSIL时。您将找到initobj !T,这是default(T)指令。这是自动完成的。因此,如果您从VB.net调用C#库,那么它也会工作。

票数 1
EN

Stack Overflow用户

发布于 2015-03-27 20:49:28

你可以用这个方法

代码语言:javascript
运行
复制
public static IList<int> ToIntList(this object values)
        {
            //try to convert using modified ChangeType which handles nullables
            try
            {
                if (values == null) return new List<int>();

                var charValues = values.ToType<string>();
                return charValues.Split(',').Select(n => Convert.ToInt32(n)).ToList();
            }
            //if there is an exception then get the default value of parameterized type T
            catch (Exception)
            {
                return new List<int>();
            }
        }

internal static object ChangeType(object value, Type conversionType)
        {
            if (conversionType == null)
            {
                throw new ArgumentNullException("conversionType");
            } 

            if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition() == typeof (Nullable<>))
            {
                if (value == null)
                {
                    return null;
                } 
                var nullableConverter = new NullableConverter(conversionType);
                conversionType = nullableConverter.UnderlyingType;
            }
            return Convert.ChangeType(value, conversionType);
        }

像这样用

代码语言:javascript
运行
复制
userVar.ToType<int>()
userVar.ToType<string>()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28133205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档