我试图根据成员名称列表将一些效率C#代码从对象A复制为object b复制所选类成员。所讨论的课程将结合字符串成员和班级成员。这是类布局的示例。
public class Class0
{
public string C0Prop1 { get; set; } = "c0.prop1";
}
public class Class1
{
public string C1Prop1 { get; set; } = "c1.prop1";
public string C1Prop2 { get; set; } = "c1.prop2";
}
public class Class2
{
public string C2Prop1 { get; set; } = "c2.prop1";
public Class1 C2Prop2 { get; set; } = new Class1();
public string C2Prop3 { get; set; } = "c2.prop3";
public string C2Prop4 { get; set; } = "c2.prop4";
public Class0 C2Prop5 { get; set; } = new Class0();
}
i然后有一个函数foo((,该函数具有'props'的列表,该列表是class2的某些成员的名称。
我的目标是拥有一些紧密的代码,以使我可以将C2Prop2和C2Prop4从源对象复制到目标对象。最终,"道具"传递给了foo((,因此它将是动态的,而foo((可以复制任何元素。
foo()
{
BindingFlags _flags = BindingFlags.GetProperty | BindingFlags.IgnoreCase |
BindingFlags.Instance | BindingFlags.Static |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.FlattenHierarchy;
Class2 source = new Class2();
Class2 dest = new Class2();
List<string> props = new List<string>() { nameof(Class2.C2Prop2), nameof(Class2.C2Prop4) };
foreach (string prop in props)
{
var s = source.GetType().GetProperty(prop, _flags).GetValue(source, null);
if (s != null)
{
if (String.Compare(prop, nameof(Class2.C2Prop2), true) == 0)
{ // one option could be json
dest.C2Prop2 = JsonConvert.DeserializeObject<Class2>(JsonConvert.SerializeObject(s));
}
else
if (String.Compare(prop, nameof(Class2.C2Prop5), true) == 0)
{ // another option for copy
dest.C2Prop5 = source.C2Prop5;
}
else
{ // this is a simple string member, just assign it.
dest.GetType().GetProperty(prop, _flags).SetValue(dest, s.ToString());
}
}
}
}
在此示例中,我要迭代" Props"列表,并使用PropertyInfo确定源成员的特征,然后确定它是类还是字符串,并相应地进行副本。我敢肯定,必须有一种更最佳的方法来一致将类对象的单个成员从源到目的地复制,但是对于我的生命,我无法完全弄清楚。
对此的任何帮助将不胜感激!
我能够为源和目标对象的propertyInfo的getSetMethod((和getGetMethod((和GetGetMethod((执行通用副本。授予这一点,假设成员需要拥有公共getters和setter,但是这种逻辑使我能够最大程度地减少代码数量。
随时推荐改进。
public void copyAttrs(List<string> props, ref Class2 source, ref Class2 dest)
{
BindingFlags _flags = BindingFlags.GetProperty | BindingFlags.IgnoreCase |
BindingFlags.Instance | BindingFlags.Static |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.FlattenHierarchy;
foreach (string prop in props)
{
var propSource = source.GetType().GetProperty(prop, _flags);
var proDest = dest.GetType().GetProperty(prop,_flags);
if ((propDest != null) && (propSource != null))
{
MethodInfo destSetMethod = propDest.GetSetMethod();
MethodInfo sourceGetMethod = propSource.GetGetMethod();
if ((destSetMethod != null) && (sourceGetMethod != null))
destSetMethod.Invoke(dest, new object[] { sourceGetMethod.Invoke(source, null) });
}
}
}