开发者

Refactor using generics

I have a simple interface with methods such as

     bool TryGetValue(string key, out string value);
     bool TryGetValue(string key, out int value);
     bool TryGetValue(string key, out double value);
     bool TryGetValue(string key, out DateTime value);
     // only value types allowed 

     //with the implementation based on dictionary<string, object> 
     bool TryGetValue(string key, out string value)
     {
        object rc;
        if ( dict.TryGetValue(key, out rc) )
        {
            value = rc.ToString();
            return true;
        }

        value = null;
        return false;
     }

Looks like a perfect case for generics as

     bool TryGetValue<开发者_运维百科;T>(string key, out T value) where T: ValueType;

except not able to work out the func implementation, anyone ?

UPDATE - the following does not compile, i'd like to avoid creating multiple TryGet... funcs !

     bool TryGetValue<T>(string key, out T value)
     {
         return dict.TryGetValue(key, out value) ;
     }


I'm guessing that what you want is this:

 bool TryGetValue<TValue>(string key, out TValue value)
 {
    object rc;
    if (dict.TryGetValue(key, out rc))
    {
        value = (TValue)rc;
        return true;
    }

    value = default(TValue);
    return false;
 }

This doesn't actually convert the values if they are the wrong type - it assumes that the generic System.Object instances sitting in the dictionary are actually of type TValue when the TryGetValue method is invoked.

If you want to restrict the method to only allow value types for the generic parameter, just change the method signature to this:

 bool TryGetValue<TValue>(string key, out TValue value) where TValue : struct

Note - JaredPar had the first answer but seems to have deleted his, so I am undeleting mine because I think it's what the OP wanted. I apologize for any unintended duplication.


Try this:

public bool TryGetValue<T>(string key, out T value) where T : struct
{
  object obj;
  var result = dict.TryGetValue(key, out obj);
  value = (T)obj;
  return result;
}

It' not pretty, but deals with the limitations of out...maybe someone can shorten it even more? If so please comment...always up to learn new ways.


Take a look at: http://msdn.microsoft.com/en-us/library/s4ys34ea.aspx it may prove useful to you. Also why not just extend Dictionary?


I believe Aaronaught has caught the main crux of the problem (capturing the object and casting/unboxing to T), but some additional points:

  • to limit to value-types(*), you use where T : struct, not where T : ValueType...
  • ...but note that string is not a value-type, so this probably isn't a good "fit"
  • ...and (*=) note that where T : struct also excludes Nullable<T>

So I think you just need to remove that constraint completely.


I'd probably go for something like this, although as Marc points out the struct constraint won't allow strings:

private static class Container<T> where T : struct
{
    public static Dictionary<string, T> Dict = new Dictionary<string, T>();
}

public bool TryGetValue<T>(string key, out T value) where T : struct
{
    return Container<T>.Dict.TryGetValue(key, out value);
}


Extension method.

namespace AssemblyCSharp
{
    public static class ExtentionMethod {

        public static bool TryGetValue<T, T2>(this Dictionary<T, T2> dict, string key, out T value) {
            return dict.TryGetValue(key, out value);
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜