简体   繁体   English

设置一个简单的等值类C#

[英]Setting up a simple iequatable class c#

Cant find a simple answer. 找不到简单的答案。 My problem is I am trying to compare the VALUE of an object in a list to the VALUE of an object... 我的问题是我正在尝试将列表中的对象的值与对象的值进行比较...

my class: 我的课:

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

I create theMatchList. 我创建了MatchList。 It seems that I can only compare the object and not the values for object with 'theMatchList.Contains...' 看来我只能用'theMatchList.Contains ...'比较对象而不是对象的值。

                            MatchList ML = new MatchList();

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

How do get to fire 'DoSomething'? 如何触发“ DoSomething”? Assuming that there is an entry in 'theMatchList' where the values equal 12 and 2.3 respectively. 假设在“ theMatchList”中存在一个条目,其中值分别等于12和2.3。 I know it has something to do with iequatable, but I dont quite understand how that works. 我知道它与等价性有关,但是我不太了解它是如何工作的。 Thanks in advance! 提前致谢!

Your naming is a bit unclear, I assume that you actually have a List<MatchList> that you want to find a particular MatchList in (I suggest renaming MatchList to at least MatchItem in that case and preferable something more descriptive). 您的命名是有点不清楚,我认为你确实有一个List<MatchList>要找到某个特定MatchList在(我建议重新命名MatchList至少MatchItem在这种情况下,且优选的更具描述性的)。

Then from the documentation of List<T>.Contains : 然后从List<T>.Contains的文档中List<T>.Contains

This method determines equality by using the default equality comparer, as defined by the object's implementation of the IEquatable<T>.Equals method for T (the type of values in the list). 此方法通过使用默认的相等比较器确定相等,该默认比较器由对象的IEquatable<T>.Equals方法实现,用于T(列表中值的类型)。

So you will have to implement IEquatable<T> for your class. 因此,您将必须为您的类实现IEquatable<T> In addition, the advice is that 另外,建议是

[i]f you implement Equals, you should also override the base class implementations of Object.Equals(Object) and GetHashCode so that their behavior is consistent with that of the IEquatable.Equals method. [i]如果实现了Equals,则还应该重写Object.Equals(Object)和GetHashCode的基类实现,以使它们的行为与IEquatable.Equals方法的行为一致。

If you implement GetHashCode , its result should not change over the lifetime of your object. 如果实现GetHashCode ,则其结果在对象的整个生命周期内不应更改。 In most cases, making the class immutable is sufficient. 在大多数情况下,使类不可变就足够了。 If you need to be able to update the fields, you need to implement GetHashCode differently. 如果需要能够更新字段,则需要以不同的方式实现GetHashCode

So all in all, if you want to use Contains your class will end up looking something like below: 因此,总而言之,如果您想使用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();
    }
}

As I commented, your question is pretty unclear so I'll do my best to explain the concept. 正如我所评论的那样,您的问题尚不清楚,因此我将尽力解释这一概念。

It's pretty likely what you were trying to code is the items in the list not the list itself: 您尝试编写的代码很可能是列表中的项目,而不是列表本身:

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!
}

You'll note that has an implementation of IEquatable<MatchItem> which allows it to be compared to other instances of MatchItem . 您会注意到,它具有IEquatable<MatchItem> ,可以将其与MatchItem其他实例进行MatchItem

Thereafter, this code will work: 此后,此代码将起作用:

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

Working example: http://rextester.com/ZWNC6890 工作示例: http : //rextester.com/ZWNC6890

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM