【问题标题】:How to assign C# dynamic variable properties to another dynamic object?如何将 C# 动态变量属性分配给另一个动态对象?
【发布时间】:2013-06-16 22:40:39
【问题描述】:

我正在尝试编写一个函数来创建类型 t 的对象并分配其属性。

    internal static object CreateInstanceWithParam(Type t, dynamic d)
    {
        //dynamic obj =  t.GetConstructor(new Type[] { d }).Invoke(new object[] { d });

        dynamic obj =  t.GetConstructor(new Type[] { }).Invoke(new object[] { });
        foreach (var prop in d.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
        {
            //prop.Name, 
            //prop.GetValue(d, null);

            // assign the properties and corresponding values to newly created object ???
        }
        return obj;
    }

那么我应该可以将它用于任何类型的类类型,例如

IUser user = (IUser)CreateInstanceWithParam(userType, new { UserID = 0, Name = "user abc", LoginCode = "abc", DefaultPassword = "xxxxxx" });

IUnit newUnit = (IUnit)CreateInstanceWithParam(unitType, new { ID = 3, Code = "In", Name = "Inch", Points = "72" })

如何将属性prop.Name 分配给obj

【问题讨论】:

  • 你为什么要使用dynamic?如果你用反射做所有事情,我看不出你实际上在做任何利用它的事情 dynamic
  • 对不起,我对Reflection命名空间了解不多。

标签: c# c#-4.0 dynamic reflection types


【解决方案1】:

假设你只是想复制属性,你根本不需要dynamic

internal static object CreateInstanceWithParam(Type type, object source)
{
    object instance = Activator.CreateInstance(type);
    foreach (var sourceProperty in d.GetType()
                                    .GetProperties(BindingFlags.Instance | 
                                                   BindingFlags.Public))
    {
        var targetProperty = type.GetProperty(sourceProperty.Name);
        // TODO: Check that the property is writable, non-static etc
        if (targetProperty != null)
        {
            object value = sourceProperty.GetValue(source);
            targetProperty.SetValue(instance, value);
        }
    }
    return instance;
}

【讨论】:

  • 谢谢,我不是在复制属性。现在,这些值只是按照问题中给出的硬编码。我只是想解耦两个程序集。
  • @SenJacob 可能会调查 automapper?
  • @SenJacob:那么你想做什么?如果您要“将属性prop.Name 分配给obj”,您需要有一个值……您想要什么值?您的评论说:“将属性和相应的值分配给新创建的对象”-以什么方式不复制属性?
  • @JonSkeet 对不起我的英语不好。我的意思是我没有复制我已经拥有的另一个对象的属性。属性和值作为动态对象给出,例如 new { UserID = 0, Name = "user abc", LoginCode = "abc", DefaultPassword = "xxxxxx" }
  • @SenJacob 不是“动态对象”;那是一个匿名类型的实例,它实际上是一个常规的静态类型class;关于它的唯一有趣的事情是:a:我们自己不创建类(编译器会),b:我们不知道类型名称
【解决方案2】:

实际上,在这里使用dynamic 可能是一件坏事;您传入的对象是匿名类型的实例 - 不需要dynamic。特别是,dynamic 成员访问与反射不同,您不能保证描述为dynamic 的对象会返回来自.GetType().GetProperties()anything;考虑ExpandoObject

但是,FastMember(在 NuGet 上可用)可能有用:

internal static object CreateInstanceWithParam(Type type, object template)
{
    TypeAccessor target = TypeAccessor.Create(type),
        source = TypeAccessor.Create(template.GetType());
    if (!target.CreateNewSupported)
            throw new InvalidOperationException("Cannot create new instance");
    if (!source.GetMembersSupported)
            throw new InvalidOperationException("Cannot enumerate members");
    object obj = target.CreateNew();
    foreach (var member in source.GetMembers())
    {
        target[obj, member.Name] = source[template, member.Name];
    }
    return obj;
}

特别是,这可以像使用反射 API 一样轻松地使用 dynamic API,而且您通常看不到其中的区别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 2023-03-29
    • 2019-03-20
    • 2016-03-09
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多