How can I return NULL from a generic method in C#?
我有一个使用这个(伪)代码的通用方法(是的,我知道IList有谓词,但我的代码没有使用IList,而是使用其他一些集合,无论如何,这与问题无关…)
1 2 3 4 5 6 7 8 9 | static T FindThing<T>(IList collection, int id) where T : IThing, new() { foreach T thing in collecion { 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. } |
这会导致生成错误
"Cannot convert null to type parameter
'T' because it could be a value type.
Consider using 'default(T)' instead."
我能避免这个错误吗?
两种选择:
- 返回
default(T) ,即如果t为引用类型(或可空值类型),则返回null ,0 为int ,'\0' 为char 等(默认值表(c reference))。 - 将t限制为具有
where T : class 约束的引用类型,然后将null 作为正常值返回
1 | return default(T); |
您只需调整约束:
1 | where T : class |
则允许返回空值。
将类约束作为第一个约束添加到泛型类型。
1 |
如果有对象,则需要进行类型转换
1 | return (T)(object)(employee); |
如果需要返回空值。
1 | return default(T); |
你的另一个选择是在你的声明末尾加上这个:
1 2 | where T : class where T: IList |
这样它将允许您返回空值。
下面是您可以使用的两个选项
1 | return default(T); |
或
1 2 | where T : class, IThing return null; |
软件工程的解决方案,
此外,您还可以使用两种值类型和可以为空的类型将其存档:
1 2 3 4 5 6 7 8 9 | static T? FindThing<T>(IList collection, int id) where T : struct, IThing { foreach T thing in collecion { if (thing.Id == id) return thing; } return null; } |
下面是一个可为空的枚举返回值的工作示例:
1 2 3 4 | public static TEnum? ParseOptional<TEnum>(this string value) where TEnum : struct { return value == null ? (TEnum?)null : (TEnum) Enum.Parse(typeof(TEnum), value); } |
接受错误的建议…以及用户
您必须在代码中添加一个比较,以确保在执行该路径时它是有效的匹配项。
否则,可能会考虑"match found"的输出参数。
上述2个答案的另一个备选方案。如果将返回类型更改为
1 2 3 4 5 6 7 8 9 | static object FindThing<T>(IList collection, int id) { foreach T thing in collecion { if (thing.Id == id) return (T) thing; } return null; // allowed now } |