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
, notwhere 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 excludesNullable<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);
}
}
}
精彩评论