0

Consider

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

if T happens to be Guid, and obj is null (does not exist in cache), an exception occurs because Guid cannot be null. Is it possible to make Get working? I tried adding a typeof(T) == typeof(Guid) check, but it is not possible to cast Guid into T. Puzzler!

Update @mihai, as doesn't work for me

enter image description here

Update2 Since Guid is not nullable, then I presume I would look for default(Guid) which is Guid.Empty. Should have put it in the original request. Thank you for everyone's contribution.

tofutim
  • 22,664
  • 20
  • 87
  • 148
  • 2
    What would you *want* to be returned in that case? If not an exception, then it would have to be some specific value. Perhaps the default value? It's up to you. The compiler won't decide for you. – Matt Johnson-Pint Jan 19 '18 at 20:25
  • default value (Guid.Empty) – tofutim Jan 19 '18 at 20:38
  • You could use reflection, to validate the underlying type. But that would be a whole different can of worms. – Greg Jan 19 '18 at 20:40
  • 2
    Note that this can be quite dangerous. For example, suppose you have `x --> 1` in your cache and you call `cache.Get("x")` -- what happens? You can cast an *unboxed* into to double, but you cannot cast a boxed int to double, and you have a boxed int here. – Eric Lippert Jan 19 '18 at 21:21

2 Answers2

3

Your problem can be solved simply checking the null case:

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

But now you have a different problem; if T is a struct, you won't know if a returned default value is due to the cache returning null or because the cached value is in fact the default one (if Guid is the only value type you are expecting then this wouldn't be much of an issue because a default Guid isn't really a valid Guid to begin with).

Solution? Return the necessary info to discern both scenarios:

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;
}
InBetween
  • 32,319
  • 3
  • 50
  • 90
  • 2
    If you want to be able to get back a nullable GUID, then *just ask for a nullable GUID*, rather than writing a super annoying method that tries to provide multiple separate values, which of course the language wasn't designed to support conveniently, or by returning an incorrect value some of the time. – Servy Jan 19 '18 at 20:34
  • @Servy I'm over here just shaking my head – Joe Phillips Jan 19 '18 at 20:35
  • I don't want a nullable Guid. – tofutim Jan 19 '18 at 20:35
  • @Servy I agree, but the answer doesn't state that it only has to work the a nullable `Guid`, the question clearly states "if `T` *happens* to be a `Guid`..." That seems to imply `T` can be many other things. I tend to answer what is being asked and not make assumptions that can be wrong, questions tend to simplify much more involved scenarios. – InBetween Jan 19 '18 at 20:36
  • @InBetween Sure, the question doesn't state what they want to happen at all. If you just want to provide what they've asked for then *there is nothing to provide*. – Servy Jan 19 '18 at 20:37
  • @tofutim So then what do you want? What is the caller of this method expecting to happen when they ask for a `Guid` that doesn't exist? (Note you should edit your question to explain what you actually want, rather than just telling me.) – Servy Jan 19 '18 at 20:38
  • Guid.Empty (the default value), but null for all nullable types; btw, I acknowledge that this is a 'why are you asking this question' - – tofutim Jan 19 '18 at 20:38
  • 1
    @tofutim Then why isn't that in the question? And what should every other non-nullable type do when it has a null value? – Servy Jan 19 '18 at 20:39
  • What do you think about following solution ? http://www.siepman.nl/blog/post/2012/03/06/Convert-to-unknown-generic-type-ChangeType-T.aspx – Mihai Alexandru-Ionut Jan 19 '18 at 20:44
1

Try

if (obj == null)
   return default(T);
else
   return (T)obj;
BlueMonkMN
  • 25,079
  • 9
  • 80
  • 146