如何处理泛型函数中的空 Guid?

Posted

技术标签:

【中文标题】如何处理泛型函数中的空 Guid?【英文标题】:How do I handle a null Guid in a generic function? 【发布时间】: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。 【参考方案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 值时应该怎么做?

以上是关于如何处理泛型函数中的空 Guid?的主要内容,如果未能解决你的问题,请参考以下文章

使用 sum 函数时如何处理 Store 中的空值

TypeScript 如何为泛型函数创建泛型类型别名?

如何为具有泛型类型的箭头函数编写流类型

如何在 Python 中对函数(即“函数模板”)进行“泛型类型提示”?

使用配置文件中的字符串来初始化泛型类型 [重复]

使用不在参数中的第一个泛型类型重载泛型函数