新人,没分,请见谅!为了不让ArrayList中不包含同样的元素,ArrayList中,已经包含了某个元素,但是Contains判断的时候,还是返回false
导致元素被重复加入List.另做的例子里面,是没有问题的,但是这里就是不行,高手帮忙推测一下,出问题的地方。调用AddTask函数,是在另一个线程中。
        //============================================================
        // 功  能 : 增加一个附件转换任务(public函数)
        // 参  数 : TTaskInfo i_AttachInfo  <- 任务信息
        // 返回值 : 无
        //============================================================
        public static void AddTask(TTaskInfo i_AttachInfo)
        {
            try
            {
                //判断任务类型
                if (i_AttachInfo.m_intPriority == CTASK.HIGH_TASK)
                {
                    //将任务添加到列表
                    if (m_SocketTaskList.Contains(i_AttachInfo) == false)
                    {
                        lock (m_SocketTaskList)
                        {
                            m_SocketTaskList.Add(i_AttachInfo);
                        }
                    }
                }
                else if (i_AttachInfo.m_intPriority == CTASK.NORMAL_TASK)
                {
                    //将任务添加到列表
                    if (m_DBTaskList.Contains(i_AttachInfo) == false)
                    {
                        lock (m_DBTaskList)
                        {
                            m_DBTaskList.Add(i_AttachInfo);                            Console.WriteLine("m_DBTaskList.Count = " + m_DBTaskList.Count);
                            for (int i = 0; i < m_DBTaskList.Count; i++)
                            {
                                Console.WriteLine(((TTaskInfo)m_DBTaskList[i]).GetInfo());
                            }
                        }
                    }
                }

解决方案 »

  1.   

    用HashTable代替。重写 GetHashCode() 方法。
      

  2.   

    元素对应类 重写GetHashCode() 使用List<T>
      

  3.   

    应该是把lock放到if (m_SocketTaskList.Contains(i_AttachInfo) == false)
    块外吧,否则可能在if后,lock前的瞬间,另一线程已把一个相同的TTaskInfo放到里面去了吧
      

  4.   

    eg:        class Person
            {
                private string name;
                public Person(String n)
                {
                    name = n;
                }            public override bool Equals(object obj)
                {
                    return name.Equals(((Person)obj).name);
                }
            }        static void Main(string[] args)
            {
                ArrayList arr = new ArrayList();            arr.Add(new Person("peter"));
                if (arr.Contains(new Person("peter")))
                {
                    Console.WriteLine("peter is already in arr");
                }
                else
                {
                    Console.WriteLine("peter is not in arr");
                }
      

  5.   

    下面是一段测试代码,出线了同样的问题。            Thread t = new Thread(new ThreadStart(ThreadProc));
                t.Start();
            }        private static void ThreadProc()
            {
                while (true)
                {
                    Elem e1 = new Elem(1, 2, "hello");                if (arr.Contains(e1) == false)
                    {
                        arr.Add(e1);
                        Console.WriteLine("arr.Count = " + arr.Count.ToString());
                    }
                    else
                    {
                        Console.WriteLine("重复的元素");
                    }                Thread.Sleep(1000);
                }
            }
        }    class Elem
        {
            static int m_static = 0;
            int m_a;
            int m_b;
            string m_s;        public Elem(int a, int b, string str)
            {
                m_a = a;
                m_b = b;
                m_s = str;
            }
        }就是因为 new 那里的问题,每次new 一个 Elem 对象,即使Elem的成员,值都一样,也被认为是不同的这个怎么处理?
      

  6.   


    public virtual bool Contains(object item)
    {
        if (item == null)
        {
            for (int j = 0; j < this._size; j++)
            {
                if (this._items[j] == null)
                {
                    return true;
                }
            }
            return false;
        }
        for (int i = 0; i < this._size; i++)
        {
            if ((this._items[i] != null) && this._items[i].Equals(item))
            {
                return true;
            }
        }
        return false;
    }
    contains的源码,所以重写下equals,以后这种问题,楼主可以直接看源码用refector
      

  7.   

    Elem类中重写equals 方法 
      

  8.   

    楼上已经说了,重写Equals方法,自己比较{1, 2, "hello"},完全相同,返回true;  
      

  9.   

    这个需要自己重载Equals方法,不然.Net是无法知道你两个不同的对象相等的标准是什么的。
      

  10.   

      Elem e1=null; 
    while (true)
      {
    e1 = new Elem(1, 2, "hello");
    试一下
      

  11.   

    这里有个警告:
    重写 Object.Equals(object o)但不重写 Object.GetHashCode()好像是需要重写 GetHashCode,怎么写啊?
      

  12.   

    前面 重写 equals 的方法,已经可以了。现在有个警告,感觉不太好,小弟是完美主义者。
      

  13.   

    根据字段的GetHashCode,组合一个返回就可以了如
    class Elem
    {
    int a;
    int b;
    string c; public override int GetHashCode()
            {
                return a.GetHashCode()^b.GetHashCode()^c.GetHashCode();
            }}
      

  14.   

    KEY是主键,字符串类型,一般来说,equals比较什么,就取哪个属性的hashcode就可以了,保持一致        
    public override bool Equals(object obj)
            {
                if (obj == null || obj.GetType() != typeof(T))
                    return false;
                return ((IEntity)this).Key.Equals(((IEntity)obj).Key);
            }        public override int GetHashCode()
            {
                return ((IEntity)this).Key.GetHashCode();
            }
      

  15.   

    如果 equals 比较多个 数值,是不是要像17楼那样写啊?17楼代码 ^ 符号是什么意思啊?
      

  16.   

    朋友,你这样是可以的,但是,如果改成这样
                Elem e1 = new Elem(1, 2, "hello");
                int i = 0;
                while (true)
                {
                    e1.m_a = i++;
    还是认为是,同一个元素,所以你的方法,治标不治本
      

  17.   

    用reflector,看ArrayList.Contains方法
      

  18.   

    反编译.NET程序为源代码的工具。