C# 如何将动态对象转换为指定类型?

C# 如何将动态对象转换为指定类型?,c#,casting,type-conversion,C#,Casting,Type Conversion,拥有类型为Dictionary的模型,并希望将其转换为Dictionary或Dictionary 我试过了 var converted = (Dictionary<string,MyType1>)model 我也是,但不起作用 异常:无法将system.object转换为x类型 如何从运行时类型(动态)转换为已知类型?没有从一个字典类型到另一个字典类型的内置转换。但是,使用,您可以轻松地从任何其他数据结构创建新词典 在您的特定示例中,您可以将其用作 var converted =

拥有类型为
Dictionary
的模型,并希望将其转换为
Dictionary
Dictionary

我试过了

var converted = (Dictionary<string,MyType1>)model
我也是,但不起作用

异常:无法将system.object转换为x类型


如何从运行时类型(动态)转换为已知类型?

没有从一个字典类型到另一个字典类型的内置转换。但是,使用,您可以轻松地从任何其他数据结构创建新词典

在您的特定示例中,您可以将其用作

var converted = model.ToDictionary(kv => kv.Key, kv => (MyType1) kv.Value);

当然,如果您的值实际上不是类型
MyType1
,这将引发异常。如果没有,则在该点调用一些自定义转换函数,而不是
(MyType1)kv.Value

没有从一个字典类型到另一个字典类型的内置转换。但是,使用,您可以轻松地从任何其他数据结构创建新词典

在您的特定示例中,您可以将其用作

var converted = model.ToDictionary(kv => kv.Key, kv => (MyType1) kv.Value);

当然,如果您的值实际上不是类型
MyType1
,这将引发异常。如果不是,则在该点调用一些自定义转换函数,而不是
(MyType1)kv.Value

我将在已知类型上放置一个静态构造函数,该构造函数接受
动态
,并从中构建已知类型。e、 g

public class SomeType
{
    public static SomeType FromDynamic(dynamic arg)
    {
         return new SomeType
         {
              SomeProperty = arg.SomeProp
         }
    }

    public int SomeProperty {get; set; }
}
然后,您只需迭代您的
字典
,然后构建新对象,如:

var dictionary = new Dictionary<string, SomeType>();
foreach(var item in model)
{
    dictionary.Add(item.Key, SomeType.FromDynamic(item.Value));
}

我会在您的已知类型上放置一个静态构造函数,它接受
动态
,并从中构建已知类型。e、 g

public class SomeType
{
    public static SomeType FromDynamic(dynamic arg)
    {
         return new SomeType
         {
              SomeProperty = arg.SomeProp
         }
    }

    public int SomeProperty {get; set; }
}
然后,您只需迭代您的
字典
,然后构建新对象,如:

var dictionary = new Dictionary<string, SomeType>();
foreach(var item in model)
{
    dictionary.Add(item.Key, SomeType.FromDynamic(item.Value));
}

以下小演示适用于简单类型:
MapDynamicToDictionary
测试显示将动态转换为字典。
MapDictionaryType
显示将字典转换为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; }
}
公共类测试
{
[事实]
公共void MapDynamicToDictionary()
{
动态d=new{Nr=1,Name=“Devon”};
var字典=TurnObjectionToDictionary(d);
Assert.Equal(2,dictionary.Keys.Count);
}
[事实]
公共void映射字典类型()
{
动态d=new{Nr=1,Name=“Devon”};
var字典=TurnObjectionToDictionary(d);
var instance=new MyType();
地图(字典、实例);
Assert.Equal(instance.Nr,1);
Assert.Equal(instance.Name,“Devon”);
}
公共静态void映射(IDictionary dictionary,T实例)
{
var attr=BindingFlags.Public | BindingFlags.Instance;
foreach(instance.GetType().GetProperties(attr)中的var prop)
{
如果(道具可写)
{
if(字典容器(道具名称))
{
var v=Convert.ChangeType(字典[prop.Name],prop.PropertyType);
prop.SetValue(实例,v);}
}
}
}
公共静态IDictionary TurnObjectOnToDictionary(对象数据)
{
var attr=BindingFlags.Public | BindingFlags.Instance;
var dict=新字典();
foreach(data.GetType().GetProperties(attr)中的var prop)
{
如果(道具可阅读)
{
dict.Add(prop.Name,prop.GetValue(data,null));
}
}
返回命令;
}
}
类MyType
{
公共int Nr{get;set;}
公共字符串名称{get;set;}
}

可以使用
TypeConverter
处理更复杂的示例。这里有一个很好的例子:

以下小演示适用于简单类型:
MapDynamicToDictionary
测试显示将动态转换为字典。
MapDictionaryType
显示将字典转换为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; }
}
公共类测试
{
[事实]
公共void MapDynamicToDictionary()
{
动态d=new{Nr=1,Name=“Devon”};
var字典=TurnObjectionToDictionary(d);
Assert.Equal(2,dictionary.Keys.Count);
}
[事实]
公共void映射字典类型()
{
动态d=new{Nr=1,Name=“Devon”};
var字典=TurnObjectionToDictionary(d);
var instance=new MyType();
地图(字典、实例);
Assert.Equal(instance.Nr,1);
Assert.Equal(instance.Name,“Devon”);
}
公共静态void映射(IDictionary dictionary,T实例)
{
var attr=BindingFlags.Public | BindingFlags.Instance;
foreach(instance.GetType().GetProperties(attr)中的var prop)
{
如果(道具可写)
{
if(字典容器(道具名称))
{
var v=Convert.ChangeType(字典[prop.Name],prop.PropertyType);
prop.SetValue(实例,v);}
}
}
}
公共静态IDictionary TurnObjectOnToDictionary(对象数据)
{
var attr=BindingFlags.Public | BindingFlags.Instance;
var dict=新字典();
foreach(data.GetType().GetProperties(attr)中的var prop)
{
如果(道具可阅读)
{
dict.Add(prop.Name,prop.GetValue(data,null));
}
}
返回命令;
}
}
类MyType
{
公共int Nr{get;set;}
公共字符串名称{get;set;}
}

可以使用
TypeConverter
处理更复杂的示例。这里有一个很好的例子:

看起来这不是正确使用动态类型。这是一个静态类型。字典对象中的所有值都是
MyType1
?@DStanley类型的吗?就是这样!检查后。。。好像是李