拥有Dictionary<string,dynamic>
类型的模型,并希望将其转换为Dictionary<string, MyType1>
或Dictionary<string, MyOtherType>
!
我已经尝试了
var converted = (Dictionary<string,MyType1>)model
未成功尝试
IConvertible iConv = model; var converted = iConv.ToType(typeof(MyOtherType), null);
也是如此,但它不起作用
异常:无法将system.object转换为x
类型
如何从运行时类型(动态)转换为众所周知的类型?
答案 0 :(得分:3)
没有从一种字典类型到另一种字典类型的内置转换。但是,使用Enumerable.ToDictionary
,您可以轻松地从任何其他数据结构创建新字典。
在您的特定示例中,您可以将其用作
var converted = model.ToDictionary(kv => kv.Key, kv => (MyType1) kv.Value);
当然,如果您的值实际上不是MyType1
类型,则会抛出异常。如果不是,则代替(MyType1) kv.Value
,在此时调用一些自定义转换函数。
答案 1 :(得分:2)
以下小型演示适用于简单类型:
MapDynamicToDictionary
测试显示将动态变为字典。
MapDictionaryToType
显示将字典转换为T类型。
您可以通过检查类型或使用as
等来改善这一点。
public class Test
{
[Fact]
public void MapDynamicToDictionary()
{
dynamic d = new { Nr = 1, Name = "Devon" };
var dictionary = TurnObjectIntoDictionary(d);
Assert.Equal(2, dictionary.Keys.Count);
}
[Fact]
public void MapDictionaryToType()
{
dynamic d = new { Nr = 1, Name = "Devon" };
var dictionary = TurnObjectIntoDictionary(d);
var instance = new MyType();
Map(dictionary, instance);
Assert.Equal(instance.Nr, 1);
Assert.Equal(instance.Name, "Devon");
}
public static void Map<T>(IDictionary<string, object> dictionary, T instance)
{
var attr = BindingFlags.Public | BindingFlags.Instance;
foreach (var prop in instance.GetType().GetProperties(attr))
{
if (prop.CanWrite)
{
if(dictionary.ContainsKey(prop.Name))
{
var v = Convert.ChangeType(dictionary[prop.Name], prop.PropertyType);
prop.SetValue(instance, v); }
}
}
}
public static IDictionary<string, object> TurnObjectIntoDictionary(object data)
{
var attr = BindingFlags.Public | BindingFlags.Instance;
var dict = new Dictionary<string, object>();
foreach (var prop in data.GetType().GetProperties(attr))
{
if (prop.CanRead)
{
dict.Add(prop.Name, prop.GetValue(data, null));
}
}
return dict;
}
}
class MyType
{
public int Nr { get; set; }
public string Name { get; set; }
}
可以使用TypeConverter
来处理更复杂的示例。很好的例子:http://putridparrot.com/blog/type-conversions-in-c/
答案 2 :(得分:1)
我会在你熟知的类型上放置一个静态构造函数,它接受s = s
.replace("`%rackname`", rName)
.replace("`%compname`", compName)
.replace("`%sysname`", sysName);
,并从中构建一个众所周知的类型。 e.g。
dynamic
然后你只需要迭代public class SomeType
{
public static SomeType FromDynamic(dynamic arg)
{
return new SomeType
{
SomeProperty = arg.SomeProp
}
}
public int SomeProperty {get; set; }
}
并建立新对象,如:
Dictionary<string,dynamic>
借用@hvd:
var dictionary = new Dictionary<string, SomeType>();
foreach(var item in model)
{
dictionary.Add(item.Key, SomeType.FromDynamic(item.Value));
}