ArrayList al1 = new ArrayList ();
ArrayList al2 = new ArrayList (); al1.Add ("1");
al1.Add ("2"); al2 = (ArrayList)al1.Clone (); al2[0] = "One";
al2[1] = "Two";楼主,试试吧,好使

解决方案 »

  1.   

    对象拷贝应使用Clone、Copy或CopyTo等方法(看具体的类而定),不能用“=”
      

  2.   

    用clone的方法应该可以解决你的问题。
      

  3.   

    ArrayList arrL = new ArrayList();
    ArrayList arrM = (ArrayList)arrL.Clone();OrArrayList arrL = new ArrayList();
    ArrayList arrM = new ArrayList();
    arrL.CopyTo(arrM);
      

  4.   

    上面的方法全只是浅层Clone,并没有改变ArrayList中对象的引用,所以不行。
      

  5.   

    acewang(平平安安过一年) ( ) 信誉:100  2004-01-06 09:21:00  得分:0 
     
     
      clone是浅拷贝,没用的
    ***********************************************
    能说详细点吗?
      
     
      

  6.   

    ArrayList al1 = new ArrayList ();
    ArrayList al2 = new ArrayList ();al1.Add ("1");
    al1.Add ("2");foreach(object obj in al1)
    {
        Type t = obj.GetType();
        Ojbect objNew = Activator.CreateInstance(t);
        al2.add(objNew)
    }
    这回楼主满意了吧
      

  7.   

    浅表clone的方法我试过了(我在注释中附的代码就是)浅表复制只是复制了数组中保存的对象的指针,并没有复制对象本身,因此不能满足我的要求。
     iamwanghui() 朋友使用的是字符串,因此可行。 luckduck(菠萝蜜) 提到的方法我都试过了,是不行的,其实这个问题的关键在于,怎么逐个复制数组中的对象!因为不是每个对象都有clone方法,并且数组中的对象类型我现在是未知的。目前能够限制的就是可以要求这些对象都是 webcontrol 的派生类的对象。我现在在研究怎么完全复制一个 webcontrol 对象
    请大家针对这个问题继续指教。
      

  8.   

    如果Button有Clone方法,这个也就容易解决了,可是Button没有。这样自己写个Button类,继承Button并实现Clone方法:
    public class MyButton : Button {
       public MyButton() : base() {}
       public MyButton Clone() {
          return (MyButton) base.MemberwiseClone();
       }
    }然后这样:
    ArrayList arrL = new ArrayList();
    ArrayList arrM = new ArrayList();MyButton btnX = new MyButton();
    btnX.Text = "original";
    arrL.Add(btnX);
    arrL.Add(new ListBox());
    ArrayList arrM = new ArrayList();

    for(int i = 0; i < arrL.Count; i ++)
    {
       arrM.Add(((MyButton)arrL[i]).Clone());
    }((Button)arrL[0]).Text = "XXX";Label1.Text = ((Button)arrM[0]).Text;这样两个ArrayList的元素就不是引用同一个对象了。
      

  9.   

    ArrayList al1 = new ArrayList ();
    ArrayList al2 = new ArrayList (); al1.Add (new Button());
    al1.Add (new ListBox()); foreach(object obj in al1)
    {
    Type t = obj.GetType();
    Object objNew = Activator.CreateInstance(t);
    al2.Add(objNew);
    }刚才的代码有错误,纯手写的,这回试试
      

  10.   

    http://www.zdnet.com.cn/developer/tech/story/0,2000081602,39156740,00.htm
      

  11.   

    哦,大家不要被我注释中的代码迷惑了,
    我的注释中的代码是为了解决这个问题试用的各种方法,罗列了出来,而不是我要用的,我需要的就是,能够得到一个完全的 arrL 的副本而已
      

  12.   

    iamwanghui() 的方法给了我一个新的思路,谢谢,
    不过你的方法丢失了原对象的所有属性,我正在尝试用CopyBaseAttributes方法复制这些属性
      

  13.   

    不明白楼主为什么要这样做
    浅层拷贝不能达到你的效果,因为新获得的数组元素中的引用和原数组对应的引用是一样的。
    所以修改一个同时另一个也改了。
    要是想实现楼主的效果岂不是要深层copy,那么楼主数组里面的相应元素对应的对象也要拷贝一分。也就是说所有的控件都要有两份。太浪费资源了。所以楼主还是不要用这种制作副本的方法了,想一些别的方法替代达到你想要的效果。一家之言,仅供参考。
      

  14.   

    foreach(object objT in arrL)
    {
    Type t = objT.GetType();
    object objM = Activator.CreateInstance(t);
    ((WebControl)objM).CopyBaseAttributes((WebControl)objT);
    arrM.Add(objM);
    }CopyBaseAttributes仍然无效,咳
      

  15.   

    CopyBaseAttributes 只复制 AccessKey、Enabled、ToolTip、TabIndex 和 Attributes 属性
      

  16.   

    cimoka(活着):
    我也很无奈,我在做一个接口,用来动态的往模板列添加任意的已定制的webcontrol,可惜在datagrid添加记录的时候,接口的InstantiateIn被反复调用,最后的结果就是,只有最后一条记录成功的添加了控件,我在InstantiateIn方法中修改代码,每次都重新 new arrl 以及 arrl 中的对象,结果就可以了。因此我怀疑是因为对象被多次调用,只有最后一次修改有效如果你有这方面的经验,我可以把源代码给你请你帮我调试。
      

  17.   

    谢谢  xixigongzhu(夕夕公主) ,
    我是做的接口,不方便去定义其它人试用的类呀,咳
      

  18.   

    楼上的请注意:不会不是你的错,但是出来蒙人就是你的不对了.To zhangbat (jim.) :
    你使用的方法的确是建立了一个ArrayList的副本但是ArrayList中的element还是reference同一块address.
    我明白你的意图,我也知道解法.
      

  19.   

    acewang(平平安安过一年):你给的那个连接,是让自己做的类具有深层复制的功能,
    可是framework 自己的类怎么办?
      

  20.   

    上面的方法都是浅拷贝,要想深拷贝也要实现ICloneable接口,实现clone方法但是不是调用MemberwiseClone()方法,而是自己分配一个(new)新对象,来实现自己的深拷贝语义
      

  21.   

    JoeM(Tao)
    大哥,知道解法就说出来嘛,
    这里有150分立即奉上
    其它50分送给其它热心的朋友 :)嫌分少的话我可以另开贴给分 :)
      

  22.   

    我的mail :[email protected]只要解决,立即给分。to:flysnowjava(一个孤独的魂灵)
    我考虑过这个问题。可以我现在只是做一个接口,如果由于这个接口要求大家把所有的工作都重做是很不人道的,毕竟webcontrl 是web 应用中的绝对主力。
      

  23.   

    There are various ways to implement deep cloning. One method is to serialize the object into a memory stream and deserialize it back into a new object. We would need to use a Binary formatter or SOAP formatter which do a deep serialization. The problem with this approach is that the class and its members (the entire object graph) have to be ed as serializable, else the formatter would through an exception.http://www.codeproject.com/dotnet/Clone.asp?print=true
      

  24.   

    继承接口ICloneablepublic abstract class BaseObject : ICloneable
    {
        /// <summary>
        /// Clone the object, and returning a reference to a cloned object.
        /// </summary>
        /// <returns>Reference to the new cloned 
        /// object.</returns>
        public object Clone()
        {
            //First we create an instance of this specific type.
            object newObject  = Activator.CreateInstance( this.GetType() );        //We get the array of fields for the new type instance.
            FieldInfo[] fields = newObject.GetType().GetFields();        int i = 0;        foreach( FieldInfo fi in this.GetType().GetFields() )
            {
                //We query if the fiels support the ICloneable interface.
                Type ICloneType = fi.FieldType.
                            GetInterface( "ICloneable" , true );            if( ICloneType != null )
                {
                    //Getting the ICloneable interface from the object.
                    ICloneable IClone = (ICloneable)fi.GetValue(this);                //We use the clone method to set the new value to the field.
                    fields[i].SetValue( newObject , IClone.Clone() );
                }
                else
                {
                    // If the field doesn't support the ICloneable 
                    // interface then just set it.
                    fields[i].SetValue( newObject , fi.GetValue(this) );
                }            //Now we check if the object support the 
                //IEnumerable interface, so if it does
                //we need to enumerate all its items and check if 
                //they support the ICloneable interface.
                Type IEnumerableType = fi.FieldType.GetInterface
                                ( "IEnumerable" , true );
                if( IEnumerableType != null )
                {
                    //Get the IEnumerable interface from the field.
                    IEnumerable IEnum = (IEnumerable)fi.GetValue(this);                //This version support the IList and the 
                    //IDictionary interfaces to iterate on collections.
                    Type IListType = fields[i].FieldType.GetInterface
                                        ( "IList" , true );
                    Type IDicType = fields[i].FieldType.GetInterface
                                        ( "IDictionary" , true );                int j = 0;
                    if( IListType != null )
                    {
                        //Getting the IList interface.
                        IList list = (IList)fields[i].GetValue(newObject);                    foreach( object obj in IEnum )
                        {
                            //Checking to see if the current item 
                            //support the ICloneable interface.
                            ICloneType = obj.GetType().
                                GetInterface( "ICloneable" , true );
                            
                            if( ICloneType != null )
                            {
                                //If it does support the ICloneable interface, 
                                //we use it to set the clone of
                                //the object in the list.
                                ICloneable clone = (ICloneable)obj;                            list[j] = clone.Clone();
                            }                        //NOTE: If the item in the list is not 
                            //support the ICloneable interface then in the 
                            //cloned list this item will be the same 
                            //item as in the original list
                            //(as long as this type is a reference type).                        j++;
                        }
                    }
                    else if( IDicType != null )
                    {
                        //Getting the dictionary interface.
                        IDictionary dic = (IDictionary)fields[i].
                                            GetValue(newObject);
                        j = 0;
                        
                        foreach( DictionaryEntry de in IEnum )
                        {
                            //Checking to see if the item 
                            //support the ICloneable interface.
                            ICloneType = de.Value.GetType().
                                GetInterface( "ICloneable" , true );                        if( ICloneType != null )
                            {
                                ICloneable clone = (ICloneable)de.Value;                            dic[de.Key] = clone.Clone();
                            }
                            j++;
                        }
                    }
                }
                i++;
            }
            return newObject;
        }
    }
      

  25.   

    终于搞定了,但不知道楼主是否看好。用Reflection来解决复制的问题。
      

  26.   

    思路:要实现复制,其实还是有个方法的,那就是Object的MemberwiseClone方法,但这个方法是保护的,不能直接调用。现在的问题是有没有办法来调用这个方法呢。
      

  27.   

    其实只要方法存在,.net还是提供了调用的方式的,那就是Reflection API了:
    先取到方法:
    MethodInfo mi = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPublic|BindingFlags.Instance);然后将arrM = arrL;这个用下面的替换:
    ArrayList arrM = new ArrayList();for(int i = 0; i < arrL.Count; i ++)
    {
    arrM.Add(mi.Invoke(arrL[i],null));
    }
      

  28.   

    关于MemberwiseClone,文档是这样描述的:
    创建当前 Object 的浅表副本。浅表副本创建与原始对象具有相同类型的新实例,然后复制原始对象的非静态字段。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制该引用但不复制被引用的对象;这样,原始对象中的引用和复本中的引用指向同一个对象。
      

  29.   

    不知楼主看上面给你的地址了没有!http://www.codeproject.com/csharp/cloneimpl_class.asp
      

  30.   

    前面提到的利用系列化的方法有如下的例子:
    /// 
    /// Clone the World object.
    /// 
    public object CloneEx()
    {
    BinaryFormatter bFormatter = new BinaryFormatter();
    MemoryStream stream = new MemoryStream();
    bFormatter.Serialize(stream, this);
    stream.Seek(0, SeekOrigin.Begin);
    World newWorld = (World)bFormatter.Deserialize(stream);
    return newWorld;
    }
      

  31.   

    //clone ,MemberwiseClone 只能复制 value Type,and object's Reference 
    //换一种方式 :定义成类
    public class myClass{
    public static ArrayList GetArray(){
    Private ArrayList arrL = new ArrayList();
    Button btnX = new Button();
    btnX.Text = "original";
    arrL.Add(btnX);
    arrL.Add(new ListBox());
    return arrL;
    }
    }
    ArrayList arrL = myClass.GetArray();
    ArrayList arrM = myClass.GetArray();
      

  32.   

    对不起,刚才开了个会,
    现在我试一下power_mj 和 xixigongzhu(夕夕公主) 的方法,谢谢大家,另外, acewang(平平安安过一年) ,我在上面有回复,我不能定义别的类的,因为我做的是接口
      

  33.   

    to:xixigongzhu(夕夕公主)
    果然如你所说,还是指向同一个对象不行的:(
    改成这样也不行
    System.Reflection.MethodInfo mi = typeof(object).GetMethod("MemberwiseClone",System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Instance); ArrayList arrL = new ArrayList();
    ArrayList arrM = new ArrayList(); Button btnX = new Button();
    btnX.Text = "original";
    arrL.Add(btnX);
    arrL.Add(new ListBox()); foreach(object objT in arrL)
    {
    object objM = new object();
    objM = mi.Invoke(objT,null);
    arrM.Add(objM);
    }
    ((Button)arrL[0]).Text = "XXX"; Label1.Text = ((Button)arrM[0]).Text;
      

  34.   

    to:cuike519(Power_mj) 
    报错,提示说“xxx.aspx 不是可序列化的对象”
    :(
      

  35.   

    值类型 <-> 引用类型浅表复制 <-> 深度复制设计理念有问题。