如何重写 List<T> 的 Contains 方法

9
我想比较List[MyObject]中的属性而不是整个对象。因此我使用IEquatable[MyObject],但编译器仍然要求使用MyObject而不是字符串属性。为什么?
以下是您提供的内容:
public class AnyClass
{
    public List<AnyOtherClass> MyProperty { get; set; }        
    public string AnyProperty { get; set; }

    public AnyClass(string[] Names, string[] Values, string AnyProperty)
    {
        this.AnyProperty = AnyProperty;
        this.MyProperty = new List<AnyOtherClass>();
        for (int i = 0; i < Names.Length; i++)
            MyProperty.Add(new AnyOtherClass(Names[i], Values[i]));
    }
}

public class AnyOtherClass : IEquatable<string>
{
    public AnyOtherClass(string Name, string Values)
    {
        this.Name = Name;
        this.Values = Values.Split(';').ToList();
    }

    public string Name { get; set; }
    public List<string> Values { get; set; }

    public bool Equals(string other)
    {
        return this.Name.Equals(other);
    }
}

    private void DoSomething()
    {
        string[] Names = new string[] { "Name1", "Name2" };
        string[] Values = new string[] { "Value1_1;Value1_2", "Value2" };
        AnyClass ac = new AnyClass(Names, Values, "any Property");

        if (ac.MyProperty.Contains("Name1")) //Problem is here...
            //do something
    }
5个回答

24

你可能想尝试使用这个:

myList.Any(x => x.someProperty == someValue);

来自MSDN:http://msdn.microsoft.com/en-us/library/bb534972.aspx

确定序列中是否有任何元素满足条件。

如果您不知道,x => x.someProperty == someValue 被称为 lambda表达式

请注意,您可以在实现 IEnumerable 的任何内容上使用此功能,因此这不会限制您只能使用 List<T>


2
我正要发布这个。当找到第一个匹配项时,Any将停止评估,而Where将继续进行以获取完整列表(可能需要更长时间才能运行)。 - Jon B
好的,我会在这里使用 LINQ。 - UNeverNo

4
听起来你应该使用 Where 而不是 Contains
string value = "test";
ac.Where(ac => ac.Name1 == value || ac.Name2 == value);

ac.MyProperty.Contains("Name1")出错的原因是MyProperty是一个List<AnyOtherClass>而不是一个string


是的,LINQ 在这里可以工作,但我仍然不明白为什么 IEquatable 不起作用。 - UNeverNo
+1 只是因为“听起来你应该使用 Where 而不是 Contains”这句话对我帮助太大了! - Izzy

3
应该使用IEquatable<AnyOtherClass>而不是<string>。你正在比较AnyOtherClass的实例,而不是String的实例,尽管你的比较实际上是在比较类中的字符串。
但是看起来更像是您想要创建某种字典。这种情况下应该使用字典类。

但我确实想将一个字符串与我的类的属性进行比较。我没有整个对象可以进行比较。 - UNeverNo
@UNeverNo:这不是 IEquatable 接口的作用。它是用于比较相同类型的对象。正如我之前所说,你真正需要的似乎不是 List<AnyOtherClass> 而是 Dictionary<string,AnyOtherClass> - Matt Burland

2
这不是IEquatable<T>的预期使用方法。请查看文档http://msdn.microsoft.com/en-us/library/ms131187.aspx
实现者注意事项:将IEquatable<T>接口的类型参数替换为实现此接口的类型。
除了不设计成这样工作,为什么要强制一个类实现equals,因为另一个类有一个关于查找实例的特定要求?让拥有集合的类按其他答案中描述的基于键的查找来完成。

0

这对我来说非常好用!

"""

public class Point : IComparable<Point>, IEquatable<Point>
{
    public DateTime x;
    public double y;
    public uint z;

    public Point(DateTime dateTime, double rate, uint sequence)
    {
        x = dateTime;
        y = rate;
        z = sequence;
    }

    public int Compare(Point a, Point b)
    {
        // Equal.
        if (a.z == b.z)
        {
            return 0;
        }
        // Less than.
        else
        if ((a.z < b.z))
        {
            return -1;
        }
        // Greater than.
        else
        {
            return 1;
        }
    }

    public int CompareTo(Point point)
    {
        return Compare(this, point);
    }

    public static int operator- (Point a, Point b)
    {
        return (int)(a.z - b.z);
    }

    public bool Equals(Point point)
    {
        return z == point.z;
    }
}

"""


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接