【问题标题】:How do I handle a null Guid in a generic function?如何处理泛型函数中的空 Guid?
【发布时间】:2018-06-29 03:45:56
【问题描述】:

考虑

    public static T Get<T>(this ICache cache, string key)
    {
        var obj = cache.Get(key);
        return (T)obj;
    }

如果 T 恰好是 Guid,而 obj 为 null(缓存中不存在),则会发生异常,因为 Guid 不能为 null。是否可以让 Get 工作?我尝试添加 typeof(T) == typeof(Guid) 检查,但无法将 Guid 投射到 T. Puzzler 中!

更新 @mihai,因为不适合我

Update2 由于 Guid 不可为空,所以我想我会寻找默认 (Guid),即 Guid.Empty。应该把它放在原始请求中。感谢大家的贡献。

【问题讨论】:

  • 在这种情况下您想要返回什么?如果不是例外,那么它必须是某个特定值。也许是默认值?由你决定。编译器不会为你做决定。
  • 默认值(Guid.Empty)
  • 您可以使用反射来验证底层类型。但那将是完全不同的蠕虫罐头。
  • 请注意,这可能非常危险。例如,假设您的缓存中有x --&gt; 1,而您调用cache.Get&lt;double&gt;("x")——会发生什么?您可以将 unboxed 强制转换为 double,但不能将已装箱的 int 强制转换为 double,而这里有一个已装箱的 int。

标签: c#


【解决方案1】:

试试

if (obj == null)
   return default(T);
else
   return (T)obj;

【讨论】:

  • default(T) 是一个很好的举措 - 但是当我想要它时它会给我 null 吗?说一个不在缓存中的字符串类型,我应该得到 null,而不是 string.Empty
  • @tofutim 返回默认值
  • 我很想` if (obj == null && typeof(T) == typeof(Guid)) return default(T);`
  • @tofutim 你不需要这样做,除非你希望其他值类型的强制转换以同样的方式失败。
  • @tofutim 是的,所有引用类型(类)默认为null。并且Nullable&lt;T&gt; 默认为等于null 的值。
【解决方案2】:

只需检查null 案例即可解决您的问题:

public static T Get<T>(this ICache cache, string key)
{
    var obj = cache.Get(key);
    return obj == null ? default(T) : (T)obj;
}

但是现在你有一个不同的问题;如果 T 是一个结构,您将不知道返回的默认值是由于缓存返回 null 还是因为缓存的值实际上是默认值(如果 Guid 是您期望的唯一值类型,那么这不是什么大问题,因为默认的Guid 并不是真正有效的Guid

解决方案?返回必要的信息来辨别这两种情况:

public static bool TryGet<T>(this ICache cache, string key, out T result)
{
    var obj = cache.Get(key);

    if (obj == null)
    {
        result = default(T);
        return false;
    }

    result = (T)obj;
    return true;
}

【讨论】:

  • 如果您希望能够取回一个可为空的 GUID,那么 只需请求一个可为空的 GUID,而不是编写一个超级烦人的方法来尝试提供多个单独的值,当然,语言不是为了方便地支持而设计的,或者有时会返回不正确的值。
  • @Servy 我在这里只是摇头
  • 我不想要一个可以为空的 Guid。
  • @Servy 我同意,但答案并没有说明它只需要为可空的Guid 工作,问题明确指出“如果T 发生成为Guid..." 这似乎暗示T 可以是很多其他的东西。我倾向于回答被问到的问题,而不是做出可能是错误的假设,问题往往会简化更多涉及的场景。
  • @tofutim 那为什么不在问题中呢?当其他所有不可为 null 的类型有 null 值时应该怎么做?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-28
  • 1970-01-01
  • 2018-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多