2013-06-20 136 views
1

我想寫一個函數,它創建一個類型爲t的對象並分配它的屬性。如何將C#動態變量屬性分配給另一個動態對象?

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.Nameobj

+2

爲什麼你使用'dynamic'?如果你用反射來做所有的事情,我看不到你實際上在做任何使用「動態」的東西。 –

+0

對不起,我對「Reflection」命名空間不太瞭解。 –

回答

3

假設你只是想複製的屬性,你不需要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; 
} 
+0

謝謝,我不復制屬性。現在這些值只是在問題中給出的硬編碼。我只是想解耦兩個組件。 –

+1

@SenJacob可能會調查automapper? –

+1

@SenJacob:你試圖做什麼?如果你要「將屬性'prop.Name'賦值給'obj'',你需要有一個值...你想要什麼值?您的評論說:「將屬性和相應的值分配給新創建的對象」 - 以什麼方式不復制屬性? –

1

其實用dynamic可能會是一個壞事情這裏;您傳入的對象是匿名類型的實例 - 不需要dynamic。特別是,dynamic成員訪問與反射不一樣,並且不能保證描述爲dynamic的對象將返回什麼有趣於.GetType().GetProperties();考慮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; 
} 

特別是,這可以很容易地使用dynamic API作爲反射API,你永遠通常看到區別。