tags:

views:

295

answers:

2

The object Row is a class, that has a property Values which is a Dictionary.

Below are extension methods on the Values property.

public static T TryGetValue<T>(this Row row, string key)
{
return TryGetValue(row, key, default(T));
}

public static T TryGetValue<T>(this Row row, string key, T defaultValue)
{
    object objValue;

    if (row.Values.TryGetValue(key, out objValue))
    {
        return (T)objValue;
    }

    return defaultValue;
}

If I do:

user.Username = user.Values.TryGetValue<string>("Username");

This happends if the key "username" is not in the Dictionary.

I get an exception, invalid cast:

The following error ocurred:

System.InvalidCastException: Specified cast is not valid.

TryGetValue[T](Row row, String key, T defaultValue) 

TryGetValue[T](Row row, String key) 

So I guess TryGetValue doesn't work on strings?

+3  A: 

It should work fine, either if the key "Username" is in the dictionary with a corresponding string value, or not in the dictionary at all.

The fact that you're getting an InvalidCastException shows that the value for the "Username" key wasn't a string.

Jon Skeet
there is another overload I didn't put in sorry.
Blankman
Does the link in Josh's answer point to something?
Blankman
@Blankman: I suggest you edit your post to clarify: 1) The overload; 2) What exactly Row is - you say it's an *object* of type `Dictionary<string, object>` but it's clearly a *type* rather than an object; 3) the exception you're getting.
Jon Skeet
ok after tracing my code, it seems if the key is not present in the dictionary, it throws an exception (invalid cast).
Blankman
@Blankman: It shouldn't do that - it should return the default value. But then again, you're calling a method you haven't shown us, so it's hard to tell...
Jon Skeet
Jon, ok see my updates, thanks!
Blankman
@Blankman: I don't believe it's really happening if Username isn't in the dictionary - it will happen if the key is in the dictionary, but with a non-string value. If you are absolutely sure it's not in the dictionary, please post a short but complete program demonstrating it...
Jon Skeet
+4  A: 

Is it possible you've got an entry in your dictionary with key "Username" whose value is not a string?

I've added comments to your method explaining how this could lead to your issue.

// I'm going to go ahead and assume your Values property
// is a Dictionary<string, object>
public static T TryGetValue<T>(this Row row, string key, T defaultValue)
{
    // objValue is declared as object, which is fine
    object objValue;

    // this is legal, since Values is a Dictionary<string, object>;
    // however, if TryGetValue returns true, it does not follow
    // that the value retrieved is necessarily of type T (string) --
    // it could be any object, including null
    if (row.Values.TryGetValue(key, out objValue))
    {
        // e.g., suppose row.Values contains the following key/value pair:
        // "Username", 10
        //
        // then what you are attempting here is (string)int,
        // which throws an InvalidCastException
        return (T)objValue;
    }

    return defaultValue;
}
Dan Tao