【问题标题】:C# 8.0 nullable reference types feature with generic parameters [closed]具有泛型参数的 C# 8.0 可空引用类型功能 [关闭]
【发布时间】:2019-12-05 16:17:57
【问题描述】:

我有一个函数:

public static object? ToType(Type type, object? value)

我想创建一个有用的快捷方式,例如:

public static T ToType<T>(object? value)
{
  return (T)ToType(typeof(T), value);
}

启用可空检查的 C# 8.0 编译器给出以下警告:

CS8601:可能的空引用分配。

函数接受stringint 和其他类型,所以我不能设置像class 这样的通用约束。此外,它可以返回null。使用T? 进行强制转换和返回会导致编译器错误。

有没有办法修复警告?

【问题讨论】:

  • return ToType(typeof(T), value) as T; ?或者您可以使用 pragma 或 attrbute 来抑制警告
  • 好吧,如果您将int 作为T 传递并且null 的值将引发异常-因为您不能将null 转换为int(同样适用于其他类型例如布尔值等)。在这种情况下,您希望发生什么?我建议也许有两个单独的方法,或者检查不可为空的类型并为不可为空的类型返回默认值? I've answered something similar here if you want to have a look.
  • @Eldar 我可能不会掩盖这样的警告。这个警告实际上应该在代码接触生产环境之前修复。
  • 如果T 被替换为string 会怎样?来电者会得到一个不好的惊喜。您应该考虑返回 [MaybeNull]T,然后在方法主体内禁止警告(当返回 [MaybeNull]T 时,编译器还不会自动执行此操作。
  • 这有点违背了强类型语言的目的......

标签: c# nullable c#-8.0 nullable-reference-types


【解决方案1】:

要让编译器不用担心 null 引用,只需确保要转换的对象不为 null。

    [return: MaybeNull]
    public static T ToType<T>(object? value)
    {
        var res = ToType(typeof(T), value) ?? new object();
        return res is T generic ? generic : default;
    }

恕我直言,以这种方式处理类型气味。你想用ToType 实现什么?也许你可以从那开始得到一些更干净的东西。

【讨论】:

  • OP 表示该函数也可以接受值类型,因此约束和new() 可能不合适。使用default(T) 可能会更好地服务您的方法,尽管我仍然不确定它是否是解决 OP 问题的可行解决方案。
  • 感谢@ForeverZer0,即使约束new() 不排除使用值类型,default 可能更好并允许删除约束。我会更新我的答案。我也认为这可能不是解决方案。我觉得这可能会“赢得”编译器警告,但肯定不会使代码更干净。
  • 我投了反对票,但没有人说为什么:p。不要误解我,我也不喜欢这种实现/处理问题的方式,但这就是解决@IgorMenshikov 问题的方法。
  • 我同意阿尔文的观点。此解决方案可以赢得编译器警告,但不会使代码更清晰。 github上的C#有关于同样问题的问题。看起来当前版本的 C# 不允许这样做干净。但从技术上讲,这个解决方案有效(我的测试通过了)。只有一个注意事项:使用静态对象而不是每次都创建一个新对象可能是合理的。这个函数可以被多次调用,结果为“null”,GC 可能不满意。
  • 很好地考虑了静态对象@IgorMenshikov。我不觉得问题出在 C# 上。我觉得语言已经到了可以做很多事情的地步,但用户必须足够聪明才能选择最佳路径。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
相关资源
最近更新 更多