检查List是否包含与给定实例相等的实例

时间:2011-10-26 18:41:26

标签: c# instance

我不想在列表中循环比较每个属性。具有此功能的东西:

class myClass
{
    public int I { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<myClass> l = new List<myClass>();

        myClass x = new myClass();
        x.I = 1;
        l.Add(x);

        myClass y = new myClass();
        y.I = 2;
        l.Add(y);

        myClass z = new myClass();
        z.I = 2;

        if (l.ContainsAnInstanceEqualTo(z))
            Console.WriteLine("Contains");

        Console.ReadLine();
    }
}

重要提示:我无法控制该类,并且有一些属性应具有相同的值。

5 个答案:

答案 0 :(得分:8)

您应该myClass实施IEquatable<myClass>(或至少覆盖Equals(object)),然后使用:

if (l.Contains(z))

(您还应该重命名该类以遵循.NET命名约定...)

如果您不提供Equals方法,则必须指定您对以某种方式感兴趣的等级。你可以通过带有谓词的Find之类的东西来做到这一点:

var found = l.Find(c => c.I == z.I);
if (found != null)
{
    ...
}

或使用LINQ:

var any = l.Any(c => c.I == z.I);

但如果 是一种自然的平等感,那么覆盖Equals会更好。

List<T>.Contains不会使用您对GetHashCode的实施,但您应该按照Equals方法实施该方法......)

答案 1 :(得分:1)

Contains方法与Predicate<myClass>

一起使用
if (l.Contains(item => item.I == z.I))
    Console.WriteLine("Contains");

答案 2 :(得分:0)

你可能会在这里混淆一​​些术语......在你的例子中,即使Y和Z具有相同的I值,它们也不是同一个实例。如果你希望要确定它们的值是否相同,您可以覆盖Object.Equals()方法,也可以使用Object.GetHashCode()方法。您甚至可以考虑以某种方式使用词典。

如果您要确定列表中是否存在您尝试添加的元素的确切实例,则可能需要考虑查看{{3} }。

答案 3 :(得分:0)

这是我尝试创建一个EqualityComparer,它应该比较任何类的公共实例属性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication2
{
    class MyClass
    {
        public int I { get; set; }
        public string S { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            HashSet<MyClass> hs = new HashSet<MyClass>(new SamePublicPropertiesInstance());

            MyClass x = new MyClass();
            x.I = 1;
            x.S = "1";
            hs.Add(x);
            MyClass y = new MyClass();
            y.I = 2;
            y.S = "1";
            hs.Add(y);
            MyClass z = new MyClass();
            z.I = 2;
            z.S = "1";
            hs.Add(z);

            foreach (MyClass m in hs)
            {
                Console.WriteLine("I: {0} S: {1}", m.I, m.S);
            }

            Console.ReadLine();
        }
    }
}

class SamePublicPropertiesInstance : EqualityComparer<object>
{
    public override bool Equals(object o1, object o2)
    {
        PropertyInfo[] pInfos = o1.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
        string pName;
        bool equal;
        MethodInfo methodInfo;

        foreach (PropertyInfo pInfo in pInfos)
        {
            pName = pInfo.Name.ToString();
            methodInfo = o1.GetType().GetProperty(pName).GetGetMethod();
            equal = methodInfo.Invoke(o1, null).ToString() 
                    == 
                    methodInfo.Invoke(o2, null).ToString();
            if (!equal) return false;
        }
        return true;
    }

    public override int GetHashCode(object o)
    {
        return 1.GetHashCode();
    }
}

答案 4 :(得分:0)

public static class ObjectExtension
{
    #region Public Methods

    public static bool ExEquals<T>(this T obj, T objToCompare)
    {
        if (typeof(T) == typeof(string))
            return StringExtension.ExEquals(obj as string, objToCompare as string);
        return obj.Equals(objToCompare);
    }

    public static bool ExHasAllEquals<T>(this T obj, params T[] objArgs)
    {
        for (int index = 0; index < objArgs.Length; index++)
            if (ExEquals<T>(obj, objArgs[index]) == false) return false;
        return true;
    }

    public static bool ExHasEquals<T>(this T obj, params T[] objArgs)
    {
        for (int index = 0; index < objArgs.Length; index++)
            if (ExEquals<T>(obj, objArgs[index])) return true;
        return false;
    }

    public static bool ExHasNoEquals<T>(this T obj, params T[] objArgs)
    {
        return ExHasEquals<T>(obj, objArgs) == false;
    }

    public static bool ExHasNotAllEquals<T>(this T obj, params T[] objArgs)
    {
        for (int index = 0; index < objArgs.Length; index++)
            if (ExEquals<T>(obj, objArgs[index])) return false;
        return true;
    }

    public static bool ExIsNone(this object obj)
    {
        if (obj == null) return true;

        if (obj.Equals(DBNull.Value)) return true;

        return false;
    }

    public static bool ExNotEquals<T>(this T obj, T objToCompare)
    {
        return ExEquals<T>(obj, objToCompare) == false;
    }

    #endregion Public Methods
}


public static class StringExtension
{
    #region Public Methods

    public static bool ExContains(this string fullText, string value)
    {
        return ExIndexOf(fullText, value) > -1;
    }

    public static bool ExEquals(this string text, string textToCompare)
    {
        return text.Equals(textToCompare, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExHasAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index]) == false) return false;
        return true;
    }

    public static bool ExHasEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return true;
        return false;
    }

    public static bool ExHasNoEquals(this string text, params string[] textArgs)
    {
        return ExHasEquals(text, textArgs) == false;
    }

    public static bool ExHasNotAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return false;
        return true;
    }

    /// <summary>
    /// Reports the zero-based index of the first occurrence of the specified string
    /// in the current System.String object using StringComparison.InvariantCultureIgnoreCase.
    /// A parameter specifies the type of search to use for the specified string.
    /// </summary>
    /// <param name="fullText">
    /// The string to search inside.
    /// </param>
    /// <param name="value">
    /// The string to seek.
    /// </param>
    /// <returns>
    /// The index position of the value parameter if that string is found, or -1 if it
    /// is not. If value is System.String.Empty, the return value is 0.
    /// </returns>
    /// <exception cref="ArgumentNullException">
    /// fullText or value is null.
    /// </exception>
    public static int ExIndexOf(this string fullText, string value)
    {
        return fullText.IndexOf(value, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExNotEquals(this string text, string textToCompare)
    {
        return ExEquals(text, textToCompare) == false;
    }

    #endregion Public Methods
}