问题是这样的,我声明了3个Hashtable容器,分别是HasListOne、HasListTwo、HasListThree.
程序一开始运行我就将这3个容器中添加同一组值,代码如下:
HasListOne.Add(myEnumerator.Key,list1);
HasListTwo.Add(myEnumerator.Key,list1);
HasListThree.Add(myEnumerator.Key,list1);
然后我将HasListOne里3个容器相同的键对应的一个值改变之后,HasListTwo和HasListThree的值也跟着改变了,我就不明白这是什么原因了,希望各位大虾能给我点意见,要怎么做才能让HasListTwo和HasListThree不会跟着HasListOne的变化而变化。谢谢

解决方案 »

  1.   

    list1是什么东西??如果是对象的话
    这个是引用
    当然会改变
      

  2.   

    因为Hashtable里存的是对象,引用对象。创建新的对象
      

  3.   

    哈哈,用new的对象加入hashtable中HasListOne.Add(myEnumerator.Key,new list1);
    HasListTwo.Add(myEnumerator.Key,new list1);
    HasListThree.Add(myEnumerator.Key,new list1);
      

  4.   

    大虾们能说具体一点吗,我的list1是另一个容器的值,是这样的:
    IDictionaryEnumerator myEnumerator1 = HasList.GetEnumerator();
    ArrayList list1 = (ArrayList) HasList[myEnumerator1.Key];
      

  5.   

    lovefootball(蟑螂(生活就是扯淡--做人要放低姿态)) 
    list1是什么东西??如果是对象的话
    这个是引用
    当然会改变请问具体应该怎么解决?
      

  6.   

    如果是arraylist
    必须重新new一个新的arraylist
    可以用Clone方法
    ArrayList list = new ArrayList();
    ArrayList temp = new ArrayList();
    temp = (ArrayList)list.Clone();这样你改变temp的值
    list就不会改了
      

  7.   

    那我上面将3个容器中添加同一组值:
    HasListOne.Add(myEnumerator.Key,list1);
    HasListTwo.Add(myEnumerator.Key,list1);
    HasListThree.Add(myEnumerator.Key,list1);
    这个该怎么改?
      

  8.   

    HasListOne.Add(myEnumerator.Key,list1.Clone());
    HasListTwo.Add(myEnumerator.Key,list1.Clone());
    HasListThree.Add(myEnumerator.Key,list1.Clone());
      

  9.   

    那你这样ArrayList temp1 = new ArrayList();
    temp1 = list1.Clone();
    ArrayList temp2 = new ArrayList();
    temp2 = list1.Clone();
    ArrayList temp3 = new ArrayList();
    temp3 = list1.Clone();
    HasListOne.Add(myEnumerator.Key,temp1);
    HasListTwo.Add(myEnumerator.Key,temp2);
    HasListThree.Add(myEnumerator.Key,temp3);
      

  10.   

    错误原因:list1是引用类型。
    另:list具体内容不知道。clone 不能深度拷贝,可能会有问题
      

  11.   

    我想错误不是出现在3个容器中添加同一组值,而是我将HasListOne里3个容器相同的键对应的一个值改变之后产生的错误,希望各位大侠有兴趣的加我QQ:673881624 详细的解决,希望有人帮我
      

  12.   

    哦,不好意思
    Clone不能深度拷贝
    所以这样还是有问题
    你只能循环这个arraylist
    Clone里面的对象
      

  13.   

    先把引用类型和值类型搞明白。再把集合的Clone()方法搞明白。再重新考虑你需要的功能是用该用保存状态的方式来实现,还是保存操作序列并且提供反项操作来实现。
      

  14.   

    键并不会引起连锁反映,关键就是值的问题。因为引用时,只要时在同一个内存中,对象在一个地方被改变,其他地方会同时更新。
    解决方法就是,将三个哈希中的值换掉,这三个值可以相同拷贝自同一个list,也可以是各自更新!
      

  15.   

    jedliu(21世纪什么最贵? 人才!) 
    能不能具体一点啊,怎么样换,又怎么样各自更新,给个例子嘛
      

  16.   

    你的list里面放的是什么?实在不行你把list里面的值Clone后重新添加到三个list中
      

  17.   

    还是clone的问题,
    ArrayList list1 = (ArrayList) HasList[myEnumerator1.Key];
    你把这句改动一下
    list1=(arraylist)haslist[..].clone();
    就可以了以前clone来clone去接过都是对haslist[..]的引用,所以出问题
      

  18.   

    楼上好多说过了,就是引用类型和值类型的问题用ADD添加时,hashtable只是添加的引用
      

  19.   

    哈哈哈哈哈!没有了解.net的机制就来做东西!太业余了吧!
      

  20.   

    那么hashtable添加值怎么添加?
      

  21.   

    这是一个深拷贝的问题, 因为浅拷贝只是复制引用, 所以HasListOne中项的改变会影响其他的hashtable, 楼主可写一个深拷贝对象的方法, 把项目添加到HasListOne后, 在往其他hashtable添加时,对每个要添加的项调用该方法,则是把另一个对象添加到中,这样不会有连带关系.关于深拷贝一般有两种处理办法.1 是序列化 2.是自己写一个方法逐字段的拷贝.
    以下是方法2摘自dnn,供楼主参考
            Public Shared Function CloneObject(ByVal ObjectToClone As Object) As Object    'Implements System.ICloneable.Clone
                Try
                    Dim newObject As Object = DotNetNuke.Framework.Reflection.CreateObject(ObjectToClone.GetType().AssemblyQualifiedName, ObjectToClone.GetType().AssemblyQualifiedName)                Dim props As ArrayList = GetPropertyInfo(newObject.GetType())                Dim i As Integer = 0                For i = 0 To GetPropertyInfo(ObjectToClone.GetType()).Count - 1
                        Dim p As PropertyInfo = CType(GetPropertyInfo(ObjectToClone.GetType())(i), PropertyInfo)                    Dim ICloneType As Type = p.PropertyType.GetInterface("ICloneable", True)
                        If CType(props(i), PropertyInfo).CanWrite Then
                            If Not (ICloneType Is Nothing) Then
                                Dim IClone As ICloneable = CType(p.GetValue(ObjectToClone, Nothing), ICloneable)
                                CType(props(i), PropertyInfo).SetValue(newObject, IClone.Clone(), Nothing)
                            Else
                                CType(props(i), PropertyInfo).SetValue(newObject, p.GetValue(ObjectToClone, Nothing), Nothing)
                            End If                        Dim IEnumerableType As Type = p.PropertyType.GetInterface("IEnumerable", True)
                            If Not (IEnumerableType Is Nothing) Then
                                Dim IEnum As IEnumerable = CType(p.GetValue(ObjectToClone, Nothing), IEnumerable)                            Dim IListType As Type = CType(props(i), PropertyInfo).PropertyType.GetInterface("IList", True)
                                Dim IDicType As Type = CType(props(i), PropertyInfo).PropertyType.GetInterface("IDictionary", True)                            Dim j As Integer = 0
                                If Not (IListType Is Nothing) Then
                                    Dim list As IList = CType(CType(props(i), PropertyInfo).GetValue(newObject, Nothing), IList)                                Dim obj As Object
                                    For Each obj In IEnum
                                        ICloneType = obj.GetType().GetInterface("ICloneable", True)                                    If Not (ICloneType Is Nothing) Then
                                            Dim tmpClone As ICloneable = CType(obj, ICloneable)
                                            list(j) = tmpClone.Clone()
                                        End If                                    j += 1
                                    Next obj
                                Else
                                    If Not (IDicType Is Nothing) Then
                                        Dim dic As IDictionary = CType(CType(props(i), PropertyInfo).GetValue(newObject, Nothing), IDictionary)
                                        j = 0                                    Dim de As DictionaryEntry
                                        For Each de In IEnum                                        ICloneType = de.Value.GetType().GetInterface("ICloneable", True)                                        If Not (ICloneType Is Nothing) Then
                                                Dim tmpClone As ICloneable = CType(de.Value, ICloneable)
                                                dic(de.Key) = tmpClone.Clone()
                                            End If
                                            j += 1
                                        Next de
                                    End If
                                End If
                            End If
                        End If
                    Next
                    Return newObject
                Catch exc As Exception
                    LogException(exc)
                    Return Nothing
                End Try
            End Function
      

  22.   

    我把问题说明白一点,我做了一个短信程序,短信程序一开始运行就要收集一堆信息,我把这些信息保存在一个命名为Hashtable HasList=new Hashtable();容器里,而且要把该容器对应的值依次的添加到
    Hashtable HasListOne=new Hashtable();
    Hashtable HasListTwo=new Hashtable();
    Hashtable HasListThree=new Hashtable();中,HasList是一个临时的容器,每10秒钟就发生一次变化,而且在发生变化的同时又要与HasListOne、HasListTwo、HasListThree分别进行比较,在HasListOne、HasListTwo、HasListThree中,多的要删除,少的要加上。完全一样了之后还要比较它们相同的键所对应的值是否相同,对值的超做也是多的删,少的加。
    最关键的是HasList、HasListOne、HasListTwo、HasListThree(也就是每个容器)中,每个容器的键对应的值的个数和含义都是相同的,每个键的值中都有一项是表示时间的。还要将HasList的时间分别和HasListOne、HasListTwo、HasListThree的时间进行比较,当HasList的时间大于HasListOne时间60秒时,HasListOne就要把时间改为HasList的时间;当HasList的时间大于HasListTwo时间120秒时,HasListTwo就要把时间改为HasList的时间;当HasList的时间大于HasListThree时间180秒时,HasListThree就要把时间改为HasList的时间。
    我的错误就是在判断当HasList的时间大于HasListOne时间60秒时,HasListOne就要把时间改为HasList的时间,时间是改了,但是HasListTwo和HasListThree的时间也跟着改了。
      

  23.   

    scow(怡红快绿),能不能给个序列化的例子啊?
      

  24.   

    还是clone的问题,
    ArrayList list1 = (ArrayList) HasList[myEnumerator1.Key];
    你把这句改动一下
    list1=(arraylist)haslist[..].clone();
    就可以了以前clone来clone去接过都是对haslist[..]的引用,所以出问题我都试验通过了,你咋还不改呢????????????????????????????????????????????????
    ????????????????????????????????????????????????????????????????????????????
      

  25.   

    list1=(arraylist)haslist[..].clone();
    这句是错的.clone()根本就点不出来嘛
      

  26.   

    ((arraylist)haslist[]).clone();
    我试过的可以的
      

  27.   

    [Serializable]
        public class A
        {
            private int _i;
            private string _s;
            private B _ob;        public int i
            {
                set { _i = value; }
                get { return _i; }
            }        public string s
            {
                set { _s = value; }
                get { return _s; }
            }        public B ob
            {
                set { _ob = value; }
                get { return _ob; }
            }
        }    [Serializable]
        public class B
        {
            private bool _b;
            public bool b
            {
                set { _b = value; }
                get { return _b; }
            }
        }    class Program
        {
            static void Main(string[] args)
            {
                A a = new A();
                a.i = 1;
                a.s = "a";
                a.ob = new B();
                a.ob.b = false;            IFormatter formatter = new BinaryFormatter();
                Stream stream = new FileStream("temp.bin", FileMode.Create, FileAccess.Write, FileShare.None);
                formatter.Serialize(stream, a);
                stream.Close();
                stream = new FileStream("temp.bin", FileMode.Open);            A ca = (A)formatter.Deserialize(stream);
                stream.Close();            PrintA(a);
                PrintA(ca);            a.i = 2;
                a.s = "c";
                a.ob = new B();
                a.ob.b = true;            PrintA(a);
                PrintA(ca);
                Console.ReadLine();
            }        static void PrintA(A a)
            {
                Console.WriteLine("A.i={0};A.s={1};A.ob.b={2}", a.i, a.s, a.ob.b);
            }
        }
      

  28.   

    ArrayList al=new ArrayList();
    al.add("1");
    al.add("2");
    ArrayList n1=(ArrayList)al.clone();
    ArrayList n2=(ArrayList)al.clone();
    n1[1]="234";
    你跟踪一下看看n2的值跟着变化吗?不变吧。
      

  29.   

    ((arraylist)haslist[..]).clone()
    这个问题超没意思…………而且感觉你用3个hashtable太浪费了…………
      

  30.   

    scow(怡红快绿)  
       本来准备翻译一下自用, 还没开始做. 嫌麻烦, 序列化好了, 即把对象先序列化再反序列化得到的对象就是深拷贝的结果.
    -------------------------
    这样做还不如直接逐字段拷贝来的简单来的快呢!
      
     
      

  31.   

    Hashtable ht1 = new Hashtable();
    Hashtable ht2 = new Hashtable();ArrayList list = new ArrayList();
    list.Add(DateTime.Now.ToString());
    int s1 = DateTime.Now.Second;
    ht1.Add(s1, list.Clone());
    Thread.Sleep(1000);
    int s2 = DateTime.Now.Second;
    ht2.Add(s2, list.Clone());
    Thread.Sleep(1000);list.Add(DateTime.Now.ToString());
    list.Add(DateTime.Now.Year.ToString());ArrayList v1 = ht1[s1] as ArrayList;
    ArrayList v2 = ht2[s2] as ArrayList;
    ------------------------
    不知道这和你要写的有多大差别,当我这样试完全没问题!