复制具有不同命名空间的两个相同对象(递归reflection)

我在c#中工作,有几个工作区有一个特定的类,在每个工作区中它总是相同的。 我希望能够拥有此类的副本,以便能够在不处理命名空间差异的情况下使用它。 例子:

namespace1 { class class1{ public class2; } class class2{ public string; } } namespace2 { class class1{ public class2; } class class2{ public string; } } 

在我复制的类中,我有一个函数将所有数据复制到命名空间的类之一。 如果我只有c#标准类型,它会工作。 一旦我处理class2对象(也来自不同的命名空间),我得到了exeption(“对象与目标类型不匹配。”)

 public Object toNamespaceClass(Object namespaceClass) { try { Type fromType = this.GetType(); Type toType = namespaceClass.GetType(); PropertyInfo[] fromProps = fromType.GetProperties(); PropertyInfo[] toProps = toType.GetProperties(); for (int i = 0; i < fromProps.Length; i++) { PropertyInfo fromProp = fromProps[i]; PropertyInfo toProp = toType.GetProperty(fromProp.Name); if (toProp != null) { toProp.SetValue(this, fromProp.GetValue(namespaceClass, null), null); } } } catch (Exception ex) { } return namespaceClass; } 

任何人都知道如何处理这种“递归reflection”。

我希望eveything是可以理解的。

谢谢再见!

编辑:我想我已经解决了(至少在我的脑海里),我明天会在工作中尝试解决方案。 如果属性不是标准类型,可以将我的函数从我的类中取出并递归使用它可能是解决方案。

我有类似的问题。 我必须使用类似的类,但仅在命名空间方面有所不同。 作为一种快速解决方案,我在下面的步骤中执

  1. 将源类序列化为XML。
  2. 在SerializedXML中,将源命名空间替换为目标命名空间。
  3. 使用目标类型进行DeSerialize。

我知道上面的方法有性能开销,但它实现快速且无错误。

BinaryFormatter在.Net 4.5中不起作用,因为它记住了实例创建的类的类型。 但是对于JSON格式,它没有。 JSON序列化程序由Microsoft在DataContractJosnSerializer中实现。

这有效:

  public static T2 DeepClone(T1 obj) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T1)); DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T2)); using (var ms = new MemoryStream()) { serializer.WriteObject(ms, obj); ms.Position = 0; return (T2)deserializer.ReadObject(ms); } } 

用法如下:

  var b = DeepClone(a); 

我解决了它,只是为了让你知道我是怎么做到的:这个解决方案很完美,因为它只处理1维数组而不是更多。

 public static Object CopyObject(Object from , Object to) { try { Type fromType = from.GetType(); Type toType = to.GetType(); PropertyInfo[] fromProps = fromType.GetProperties(); PropertyInfo[] toProps = toType.GetProperties(); for (int i = 0; i < fromProps.Length; i++) { PropertyInfo fromProp = fromProps[i]; PropertyInfo toProp = toType.GetProperty(fromProp.Name); if (toProp != null) { if (toProp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary") { if (!toProp.PropertyType.IsArray) { ConstructorInfo ci = toProp.PropertyType.GetConstructor(new Type[0]); if (ci != null) { toProp.SetValue(to, ci.Invoke(null), null); toProp.SetValue(to, gestionRefelexion.CopyObject(fromProp.GetValue(from, null), toProp.GetValue(to, null)), null); } } else { Type typeToArray = toProp.PropertyType.GetElementType(); Array fromArray = fromProp.GetValue(from, null) as Array; toProp.SetValue(to, copyArray(fromArray, typeToArray), null); } } else { toProp.SetValue(to, fromProp.GetValue(from, null), null); } } } } catch (Exception ex) { } return to; } public static Array copyArray(Array from, Type toType) { Array toArray =null; if (from != null) { toArray= Array.CreateInstance(toType, from.Length); for (int i = 0; i < from.Length; i++) { ConstructorInfo ci = toType.GetConstructor(new Type[0]); if (ci != null) { toArray.SetValue(ci.Invoke(null), i); toArray.SetValue(gestionRefelexion.CopyObject(from.GetValue(i), toArray.GetValue(i)), i); } } } return toArray; } 

希望这可以帮助一些人。 谢谢你们帮助大家。 干杯

 public static T DeepClone(T obj) { using (var ms = new MemoryStream()) { var formatter = new BinaryFormatter(); formatter.Serialize(ms, obj); ms.Position = 0; return (T) formatter.Deserialize(ms); } } 

从这里

来自不同命名空间的两个相同或相似的对象?

你有这个:

 namespace Cars { public class car { public string Name; public void Start() { ... } } } namespace Planes { public class plane { public string Name; public void Fly() { ... } } } 

是时候应用一些类inheritance了:

 namespace Vehicles { public class vehicle { public string Name; } // class } // namespace using Vehicles; namespace Cars { public class car: vehicle { public string Name; public void Start() { ... } } // class } // namespace using Vehicles; namespace Planes { public class plane: vehicle { public void Fly() { ... } } } 

要复制,有一个复制方法或构造函数,但是,我更喜欢自定义的:

 namespace Vehicles { public class vehicle { public string Name; public virtual CopyFrom (vehicle Source) { this.Name = Source.Name; // other fields } } // class } // namespace 

干杯。

您需要将所有重复的类重构为单个共享类,或者实现所有各个类实现的公共接口。 如果您确实无法修改基础类型,请为实现公共接口的每个类创建一个子类。

是的,你可以用reflection做到这一点……但是你真的不应该这样做,因为你最终会遇到脆弱,容易出错的代码。

使用协议缓冲区可以优雅地解决此问题,因为协议缓冲区不包含有关它们序列化类型的任何元数据。 具有相同字段和属性的两个类序列化为完全相同的位。

这是一个小function,将从原始类型更改为C副本类型

 static public C DeepCopyChangingNamespace(O original) { using (MemoryStream ms = new MemoryStream()) { Serializer.Serialize(ms, original); ms.Position = 0; C c = Serializer.Deserialize(ms); return c; } } 

用法是

 namespace1.class1 orig = new namespace1.class1(); namespace2.class1 copy = DeepCopyChangingNamespace(orig);