2016-07-26 71 views
0

不能找到一个简单的答案。我的问题是我想的对象的值进行比较,在列表中的一个对象的价值...设置一个简单的iequatable类c#

我的课:

public class MatchList 
    { 
     public int SomeInt { get; set; } 
     public decimal SomeDecimal { get; set; } 
    } 

创建theMatchList。看来我只能比较的对象,而不是值与对象theMatchList.Contains ......“

      MatchList ML = new MatchList(); 

          ML.SomeInt = 12; 
          ML.SomeDecimal = 2.3; 
          if (theMatchlist.Contains(ML)) 
          { 
           DoSomething; 
          } 

如何获得火“DoSomething的”?假设'theMatchList'中有一个条目分别等于12和2.3。我知道这与iequatable有关,但我不太明白这是如何工作的。提前致谢!

+0

后缀的东西'List'意味着它包含的项目列表。但是你的定义似乎只包含2个标量值。所以我很困惑你的问题 - 是'MatchList'列表?列表中的项目看起来像什么?通常,列表应该是“IEnumerable”或“IList”。你的'MatchList'不包含'Contains'的定义。代码中的'theMatchList'是什么?你的问题引发了更多的问题。 – Jamiec

+0

是'列表'类型的'theMatchlist'? – sebingel

回答

1

你的命名是有点不清楚,我认为你确实有,你想找到一个特定的MatchList(我建议重新命名MatchList至少在这种情况下,且优选的更具描述性的MatchItem)一List<MatchList>

然后从List<T>.Contains文档:

该方法通过使用默认的相等比较器确定平等,如由对象的实现T的IEquatable<T>.Equals方法(值的列表中的类型)的定义。

所以,你将必须实现IEquatable<T>为你的类。此外,该建议是

[我] F你实现equals,你也应该重写的Object.Equals(对象)和GetHashCode的基类的实现,使他们的行为与该IEquatable一致。等于方法。

如果您实现GetHashCode,则其结果不应在对象的生命周期中发生变化。在大多数情况下,使类不变是足够的。如果您需要更新字段,则需要以不同方式实施GetHashCode

因此,所有的一切,如果你想使用Contains类最终会看起来像下面的东西:

public class MatchList : IEquatable<MatchList> 
{ 
    // Note: Fields are readonly to satisfy GetHashCode contract 
    private readonly int someInt; 
    private readonly decimal someDecimal; 

    // Public constructor creates immutable object 
    public MatchList(int myInt, decimal myDecimal) 
    { 
     this.someInt = myInt; 
     this.myDecimal = myDecimal; 
    } 

    // Properties are now read-only too. 
    public int SomeInt { get { return this.someInt; } } 
    public decimal SomeDecimal { get { return this.someDecimal; } } 

    // Implementation of IEquatable<MatchList> 
    public bool Equals(MatchList other) 
    { 
     return (other != null) 
      && (this.SomeInt == other.SomeInt) 
      && (this.SomeDecimal == other.SomeDecimal); 
    } 

    // Override of Object.Equals 
    // Calls the IEquatable.Equals version if possible. 
    public override bool Equals(object obj) 
    { 
     return (obj is MatchList) && this.Equals(obj as MatchList); 
    } 

    public override int GetHashCode() 
    { 
     return (this.someInt * 17)^this.someDecimal.GetHashCode(); 
    } 
} 
+0

你应该在'Equals(MatchList other)'中检查'null'。而'^'(xor)而不是'+'会产生更好的散列函数。 –

+0

谢谢@EliArbel,更新。由于'GetHashCode',这个类也是不可变的。 – CompuChip

+0

每次我需要'IEquatable'时,结果都比我想象的要多得多。 – CompuChip

0

正如我评论,你的问题是不太清楚,所以我会尽我所能解释这个概念。

这很可能是你所想要的代码是列表不是项目列表本身:

public class MatchItem : IEquatable<MatchItem> 
{ 
    public int SomeInt { get; set; } 
    public decimal SomeDecimal {get; set; } 

    public bool Equals(MatchItem item) 
    { 
     if(item == null) 
      return false; 

     return this.SomeInt == item.SomeInt && this.SomeDecimal == item.SomeDecimal; 
    } 

    // You should also override object.ToString, object.Equals & object.GetHashCode. 
    // Omitted for brevity here! 
} 

你会注意到,有IEquatable<MatchItem>实现这使得它能够被比较MatchItem的其他实例。

此后,该代码将工作:

var items = new List<MatchItem>() 
{ 
    new MatchItem{SomeInt = 1, SomeDecimal = 0.3M}, 
    new MatchItem{SomeInt = 12, SomeDecimal = 2.3M} 
}; 

var searchItem = new MatchItem{SomeInt = 1, SomeDecimal = 0.3M}; 

Console.WriteLine(items.Contains(searchItem)); // true 

工作例如:http://rextester.com/ZWNC6890