如何处理泛型函数中的空 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 --> 1
,而您调用cache.Get<double>("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<T>
默认为等于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?的主要内容,如果未能解决你的问题,请参考以下文章