写程序,用反射深度复制只有公用成员变量(public field)的类(其中类成员仍旧是只有公用成员变量的类)例如public class ABC { public int ID; public string Name; public ABC Child; } 该如何实现啊?

解决方案 »

  1.   

    深度复制不是struct吗?怎会是class
      

  2.   

    既然都说是用反射了,当然是看System.Type类了,利用这个类,可以在不知道类类型的情况下动态创建实例,调用已有实例的方法属性,获取或者设置属性值。能做这些之后,复制也不是什么问题了,深度复制最多也就是个递归的过程而已
      

  3.   

    不知道你说的复制方法是什么意思复制属性和字段的类,不完整,有很多地方没考虑
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;namespace CopyObject
    {
       public class CopyObject
       {
          public virtual object Copy(object SourceObject)
          {
             if (SourceObject == null)
             {
                return null;
             }
             _sourceType = SourceObject.GetType();
             _sourceObject = SourceObject;         if (_sourceType.IsValueType)
             {
                _result = SourceObject;
             }
             else
             {
                _result = CreateInstance();
             }
             if (!IsOriginalType())//如果不是c#内置数据类型,则对其进行递归复制
             {
                CopyProperties();
                CopyFields();
             }
             return _result;
          }      protected virtual bool IsOriginalType()
          {//判断_sourceType是否是c#内置类型,没写完
             if (_sourceType == typeof(System.Int32))
             {
                return true;
             }
             if (_sourceType == typeof(System.String))
             {
                return true;
             }
             if (_sourceType.BaseType == typeof(Enum))
             {
                return true;
             }
             return false;
          }
          protected virtual void CopyFields()
          {
             FieldInfo[] Fields = _sourceType.GetFields();
             foreach (FieldInfo Field in Fields)
             {
                Field.SetValue(_result, (new CopyObject()).Copy(Field.GetValue(_sourceObject)));
                //因为字段的类型可能也是一个类,即需要深度复制,所以递归调用
             }
          }      protected virtual void CopyProperties()
          {
             PropertyInfo[] Propertyies = _sourceType.GetProperties();
             foreach (PropertyInfo Property in Propertyies)
             {
                Property.SetValue(_result, (new CopyObject()).Copy(Property.GetValue(_sourceObject, null)), null);//对属性的取值和赋值没考虑属性有index的情况,同时因为属性可能是一个类,所以递归调用
             }
          }      protected virtual object CreateInstance()
          {
             ConstructorInfo Constructor;
             Constructor = _sourceType.GetConstructor(new Type[0]);
             if (Constructor == null)
             {
                throw (new Exception("没有找到源对象的无参构造函数"));
             }
             return Constructor.Invoke(new Type[0]);
          }
          private object _result, _sourceObject;
          private System.Type _sourceType;
       }
    }
    简单的测试代码:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using CopyObject;namespace TestCopyObject
    {
       public class LinkList
       {
          public LinkList()
          {
             Data = null;
             Next = null;
          }
          public enum even{even, uneven};
          public even IsEven;
          public object Data;
          public LinkList Next;
       }
       class Program
       {      
          static void Main(string[] args)
          {
             LinkList oCopyTest = new LinkList(), tmp, Tail, Result;
             Tail = oCopyTest;
             for (int i = 0; i < 10; ++i)
             {
                tmp = new LinkList();
                tmp.IsEven = ((i % 2 == 0) ? LinkList.even.even : LinkList.even.uneven);
                tmp.Data = (object)i;
                tmp.Next = null;
                Tail.Next = tmp;
                Tail = tmp;
             }
             CopyObject.CopyObject CopyTest = new CopyObject.CopyObject();
             Result = (LinkList)CopyTest.Copy(oCopyTest);
             Console.WriteLine(Result == oCopyTest);
             tmp = Result;
             while (tmp != null)
             {
                Console.WriteLine(tmp.Data);
                tmp = tmp.Next;
             }
             Console.ReadLine();
          }
       }
    }