我有一个通用的方法与这个(dummy)代码(是的,我知道IList有谓词,但我的代码不是使用IList而是一些其他的集合,无论如何这是无关紧要的问题…)

    static T FindThing<T>(IList collection, int id) where T : IThing, new()
    {
        foreach (T thing in collection)
        {
            if (thing.Id == id)
                return thing;
        }
        return null;  // ERROR: Cannot convert null to type parameter 'T' because it could be a value type. Consider using 'default(T)' instead.
    }

这给了我一个构建错误

"不能将null转换为类型参数 因为它可以是一个值类型。 考虑使用‘default(T)’。”

我能避免这个错误吗?


当前回答

采取错误的建议……和用户default(T)或new T。

如果您走那条路,您必须在代码中添加一个比较,以确保它是一个有效的匹配。

否则,可能会考虑“匹配已找到”的输出参数。

其他回答

return default(T);

因为IThing是接口不可能使用null。因此,必须使用default(T)来确定实际类型T的默认值,该类型T是在调用函数之前定义的。

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        
        IThing x = new List<Thing>().FindThing(1);
        
    }

}

public static class Ext {
    public static T FindThing<T>(this IList<T> collection, int id) where T : IThing, new()
    {
        foreach (T thing in collection)
        {
            if (thing.Id == id) return (T)thing;
        }
    
        //return null; //not work
        //return (T)null; //not work
        //return null as T; //not work
        return default(T); //work
    }
}

public interface IThing { int Id {get; set;} }
public class Thing : IThing { public int Id {get;set;}}

采取错误的建议……和用户default(T)或new T。

如果您走那条路,您必须在代码中添加一个比较,以确保它是一个有效的匹配。

否则,可能会考虑“匹配已找到”的输出参数。

三个选项:

Return default (or default(T) for older versions of C#) which means you'll return null if T is a reference type (or a nullable value type), 0 for int, '\0' for char, etc. (Default values table (C# Reference)) If you're happy to restrict T to be a reference type with the where T : class constraint and then return null as normal If you're happy to restrict T to be a non-nullable value type with the where T : struct constraint, then again you can return null as normal from a method with a return value of T? - note that this is not returning a null reference, but the null value of the nullable value type.

你的另一个选择是在你的声明后面加上这个:

    where T : class
    where T: IList

这样它将允许您返回null。