none
List<>.Contains 是怎麼比對的? RRS feed

  • 問題

  • 我有一個泛行物件
    裡面塞NonTranslateMessageInfo
    我測試第一次塞入TeacherName = 123 , Message  = 123 是正常的
    但是第二次塞入TeacherName = 123 , Message  = 123 居然在nontranslateMessageList.Contains時,她居然認為兩筆資料是不同的?
    其實我的需求很簡單就是有個List裡面有兩個欄位TeacherName,Message
    如果這兩個欄位資料重複時則不作任何新增動作
    如果兩個欄位資料不同時則新增進去List

    程式碼為下
        public class NonTranslateMessageInfo
        {
            public string TeacherName { get; set; }
            public string Message { get; set; }
        }

        public class Message
        {
            private List<NonTranslateMessageInfo> nontranslateMessageList;

            public boolAddMessage(int TeacherId , string TeacherName, string Message)
            {
                NonTranslateMessageInfo info = new NonTranslateMessageInfo{TeacherName =TeacherName , Message = Message};
                if(!nontranslateMessageList.Contains(info))
                {
                    nontranslateMessageList.Add(info);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

    2008年6月16日 下午 03:15

解答

  •  public class NonTranslateMessageInfo
        {
            public string TeacherName { get; set; }
            public string Message { get; set; }
        }

        public class Message
        {
            private List<NonTranslateMessageInfo> nontranslateMessageList;

            public boolAddMessage(int TeacherId , string TeacherName, string Message)
            {
                NonTranslateMessageInfo info = new NonTranslateMessageInfo{TeacherName =TeacherName , Message = Message};
                if(nontranslateMessageList.Where(m=?m.TeacherName==TeacherName && m.Message==Message).Count()==0)
                {
                    nontranslateMessageList.Add(info);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

     

    用.NET 3.5 LINQ 方式.

     


    2008年6月19日 上午 12:28

所有回覆

  • 參考下列程式碼:

    public class NonTranslateMessageInfo
    {
        public string TeacherName { get; set; }
        public string Message { get; set; }
     
        public override bool Equals(object obj)
        {
            if (obj is NonTranslateMessageInfo)
            {
                var nm = (NonTranslateMessageInfo) obj;
                return (nm.TeacherName == TeacherName && nm.Message == Message);
            }
            return false;
        }
     
        public override int GetHashCode()
        {
            return string.Format("{0}{1}", TeacherName, Message).GetHashCode();
        }
    }

    2008年6月16日 下午 04:55
  • 所以要自己實做Equals囉?
    有沒有其他更好的方法阿
    2008年6月17日 上午 02:54
  • 如果你認為系統內建的不好,本來就要自己實做機制來自訂啊。

    難不成系統自己會幫你生?

    2008年6月17日 上午 11:28
    版主
  • 想知道Contains是怎麼比對的請參考以下節錄自List.cs的List類別原始碼

    Code Snippet

            // Contains returns true if the specified element is in the List.
            // It does a linear, O(n) search.  Equality is determined by calling
            // item.Equals().
            //
            public bool Contains(T item) {
                if ((Object) item == null) {
                    for(int i=0; i<_size; i++)
                        if ((Object) _items[i] == null)
                            return true;
                    return false;
                }
                else {
                    EqualityComparer<T> c = EqualityComparer<T>.Default;
                    for(int i=0; i<_size; i++) {
                        if (c.Equals(_items[i], item)) return true;
                    }
                    return false;
                }
            }

     

     

    Default 屬性會檢查型別 T 是否實作 System.IEquatable 泛型介面,如果實作,則會傳回使用該實作的 EqualityComparer。否則,會傳回 EqualityComparer,其使用 T 所提供之 Object.EqualsObject.GetHashCode 的覆寫。

    上面這一段後半段就是說明chhuang為什麼要那樣做。

    http://msdn.microsoft.com/zh-tw/library/ms224763(VS.85).aspx

    2008年6月18日 上午 04:55
  • 1.我不知道他再問什麼?他好像連實體是什麼都還搞不懂.

    2.我不知道比較機制,但Chhung 的應該可以試.

    3.Chhung 應該是最簡單了.

    4.Chhung 他就覺得複雜了. Eric Tsai 對他來說更糟.

     

    以下就說明一下:

    ClassA a=new ClassA();

    a.Message="a";

    a,SerCode=1;

    List<ClassA) alst=new List<ClassA>();

    alst.Add(a);

    a.Message="b";

    alst.Contains(a);///這裡回傳是True 因為是同一實體,你改變內容他還是只到同一實體.

    a=new ClassA();

    a.Message="a";

    alst.Contains(a);//這裡回傳False 因為他雖然內容一樣但是不同實體.

     

     

     

    2008年6月18日 上午 05:44
  •  public class NonTranslateMessageInfo
        {
            public string TeacherName { get; set; }
            public string Message { get; set; }
        }

        public class Message
        {
            private List<NonTranslateMessageInfo> nontranslateMessageList;

            public boolAddMessage(int TeacherId , string TeacherName, string Message)
            {
                NonTranslateMessageInfo info = new NonTranslateMessageInfo{TeacherName =TeacherName , Message = Message};
                if(nontranslateMessageList.Where(m=?m.TeacherName==TeacherName && m.Message==Message).Count()==0)
                {
                    nontranslateMessageList.Add(info);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

     

    用.NET 3.5 LINQ 方式.

     


    2008年6月19日 上午 12:28