是否可以在C#中剔除参数参数?我有:
Dictionary<string,object> dict; // but I know all values are strings
string key, value;
粗略地说(如果我没有静态类型),我想这样做:
dict.TryGetValue(key, out value);
但这显然无法编译,因为它“无法从'out string‘转换为'out object'”。
我使用的解决方法是:
object valueAsObject;
dict.TryGetValue(key, out valueAsObject);
value = (string) valueAsObject;
但这似乎相当尴尬。
有没有什么语言特性可以让我在方法调用中抛出一个参数,所以它会为我做这个切换?我找不到任何有用的语法,我似乎也找不到谷歌的任何东西。
发布于 2009-08-27 21:05:23
我不知道这是不是一个好主意,但你可以添加一个泛型扩展方法:
static bool TryGetTypedValue<TKey, TValue, TActual>(
this IDictionary<TKey, TValue> data,
TKey key,
out TActual value) where TActual : TValue
{
TValue tmp;
if (data.TryGetValue(key, out tmp))
{
value = (TActual)tmp;
return true;
}
value = default(TActual);
return false;
}
static void Main()
{
Dictionary<string,object> dict
= new Dictionary<string,object>();
dict.Add("abc","def");
string key = "abc", value;
dict.TryGetTypedValue(key, out value);
}
发布于 2020-08-01 17:23:20
我用我的小眼睛发现了一个月前仍然活跃的旧帖子……下面是你要做的:
public static class DictionaryExtensions
{
public static bool TryGetValueAs<Key, Value, ValueAs>(this IDictionary<Key, Value> dictionary, Key key, out ValueAs valueAs) where ValueAs : Value
{
if(dictionary.TryGetValue(key, out Value value))
{
valueAs = (ValueAs)value;
return true;
}
valueAs = default;
return false;
}
}
因为编译器很棒,所以你可以这样叫它:
dict.TryGetValueAs(key, out bool valueAs); // All generic types are filled in implicitely! :D
但是假设你不是在创建一个黑板AI,只需要调用这个操作一次。你可以像这样简单地做一个快速涂鸦内联:
var valueAs = dict.TryGetValue(key, out var value) ? (bool)value : default;
我知道这些答案已经给出了,但它们一定是相当古老的,因为没有很酷的时尚现代内联来将这些方法压缩到我们真正想要的大小:不超过1行。
发布于 2016-07-08 01:35:38
我使用了Marc的扩展方法,但添加了一点。
我对原文的问题是,在某些情况下,我的字典会包含一个int64,而我期望的是一个int32。在其他情况下,字典将包含一个字符串(例如"42"),而我希望将其作为int。
在Marc的方法中没有办法处理转换,所以我添加了将委托传递给conversion方法的功能:
internal static bool TryGetTypedValue<TKey, TValue, TActual>(
this IDictionary<TKey, TValue> data,
TKey key,
out TActual value, Func<TValue, TActual> converter = null) where TActual : TValue
{
TValue tmp;
if (data.TryGetValue(key, out tmp))
{
if (converter != null)
{
value = converter(tmp);
return true;
}
if (tmp is TActual)
{
value = (TActual) tmp;
return true;
}
value = default(TActual);
return false;
}
value = default(TActual);
return false;
}
你可以这样调用它:
int limit;
myParameters.TryGetTypedValue("limitValue", out limit, Convert.ToInt32)
https://stackoverflow.com/questions/1343704
复制相似问题