我有这个方法
public string DictionaryToString<T, U>(Dictionary<T, U> dict)
{
var valueStrings = dict.Select(x => x.Key.ToString() + ": " + x.Value.ToString());
return String.Join("\n", valueStrings);
}
我有这个对象,我想传递给它
if ((value !=null) && value.GetType().IsGenericType &&
value.GetType().GetGenericTypeDefinition() == typeof (Dictionary<,>))
{
var castValue = value as Dictionary<,>; // this cast does not work
return DictionaryToString(castValue);
}
else
{
return value.ToString();
}
我可以在.Net 4.5中使用这样的反射代码
var targetMethodInfo = typeof(MyType).GetMethod("DictionaryToString");
var valueTypeArgs = value.GetType().GenericTypeArguments;
var genericMethod = targetMethodInfo.MakeGenericMethod(valueTypeArgs);
var result = genericMethod.Invoke(this, new[] {value });
return result.ToString();
但Type.GenericTypeArguments
是.Net 4.5中的新功能。那么如何在.Net 4.0中进行演员表演?
答案 0 :(得分:3)
你只是在密钥和值上调用ToString
,所以只需让这个方法采用IDictionary
(非泛型),你没有在那里使用任何类型特定于{ {1}}或T
。
然后,您可以简单地将所有参数转换为U
:
IDictionary
您可能还需要修改var d = arg as IDictionary;
if (d != null)
{
var res = DictionaryToString(d);
}
实施:
DictionaryToString
或者,如果你真的想使用LINQ,你可以尝试转换为static string DictionaryToString(IDictionary d)
{
var vals = new List<string>();
foreach (DictionaryEntry de in d)
{
vals.Add(de.Key.ToString() + ": " + de.Value.ToString());
}
return String.Join("\n", vals);
}
(它不可能转换为其他任何东西,因为这可能是一个通用字典(dynamic
)或非通用散列表(KeyValuePair<>
)):
DictionaryEntry
这基本上是&#34;鸭子类型&#34;存在var valueStrings = d.Cast<dynamic>().Select(de => de.Key.ToString() + ": " + de.Value.ToString());
return string.Join("\n", valueStrings);
和Key
属性。
答案 1 :(得分:1)
这听起来可能是旧System.Collections
命名空间的情况:
private static string DictionaryToString(IDictionary dict) {
if (null == dict) throw new ArgumentNullException("dict");
var valueStrings = new List<string>();
foreach (DictionaryEntry item in dict) {
valueStrings.Add(item.Key + ": " + item.Value);
}
return string.Join("\n", valueStrings.ToArray());
}
private static string Test(object value) {
var dict = value as IDictionary;
if (dict != null) {
return DictionaryToString(dict);
}
if (value == null) {
return null;
}
return value.ToString();
}
private static void Main(string[] args) {
var aDictionary = new Dictionary<int, string> {
{ 1, "one" },
{ 2, "two" },
{ 3, "three" }
};
Console.WriteLine(Test(aDictionary));
var anotherDictionary = new Dictionary<string, object> {
{ "one", 1 },
{ "two", "2" },
{ "three", new object() }
};
Console.WriteLine(Test(anotherDictionary));
Console.ReadLine();
}
<强>推理:
非通用IDictionary
将是键值对的集合,其中键为object
,值为object
。 object
支持ToString
的所有实例,因此集合的所有键和值都可以在不知道其特定类型的情况下转换为string
。
这不起作用的原因:
var castValue = value as Dictionary<,>
是因为泛型类型Dictionary<TKey, TValue>
需要2个类型参数。如果没有这些类型参数,则集合不是通用的。如果您在编译时不知道键或值类型,那么最好使用非泛型IDictionary
。
答案 2 :(得分:0)
GetGenericTypeDefinition可用于以前的版本http://msdn.microsoft.com/en-us/library/system.type.getgenerictypedefinition(v=vs.100).aspx。我认为MSDN上的4.5页缺少“其他版本”下拉列表。
答案 3 :(得分:0)
为什么不呢?
if ((value !=null) && value.GetType().IsGenericType &&
value.GetType().GetGenericTypeDefinition() == typeof (Dictionary<,>))
{
return DictionaryToString(castValue);
}
else
{
return value.ToString();
}
答案 4 :(得分:0)
您可以在.NET 4.0中强制转换为dynamic
。先前的typeof(Dictionary<,>)
检查将确保您不会遇到运行时错误。
var castValue = value as dynamic;
return DictionaryToString(castValue);