【问题标题】:Checking list for custom object自定义对象的检查列表
【发布时间】:2020-08-10 09:44:15
【问题描述】:

如果您制作了自定义对象列表,如果您想在添加之前检查该列表以查看它是否包含对象,那么必须与哈希码有关,我的意思是这样您就不会在列表还是有一种更简单的方法,基本上我想在自定义对象列表上使用 contains 方法来查看我要添加的对象是否已经存在于列表中,如果有更简单的方法则必须处理哈希码?

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataConverter.Objects;

namespace DataConverter.Converters
{
    class CategoryConverter
    {
        private Category category;
        private SubCategory subCategory;
        private ExcellObj excellObj; 
         


        public CategoryConverter(string path)
        {
            excellObj = new ExcellObj(path); 
        }

        public List<Category> getCategoryListExcel()
        {
            List<Category> categories = new List<Category>();

            List<string> ColumnNames = new List<string> { "Group1", "Group1Descr" };
            List<int> CorrectColumn = new List<int>(); 


            for(int i = 0; i < ColumnNames.Count; i++)
            {
                CorrectColumn.Add(excellObj.findColumn(ColumnNames[i]));
            }

            
            for(int i = 2; i < excellObj.allRows; i++)
            {   
              
                   
                
                    categories.Add(category = new Category(excellObj.getValuesFromCell(i, CorrectColumn[1]), excellObj.getValuesFromCell(i, CorrectColumn[0]), "Home"));
                
              
            }


            





            return categories; 


        }
        public List<List<SubCategory>> getSubCategory()
        {
            List<SubCategory> subCategories1 = new List<SubCategory>();
            List<SubCategory> subCategories2 = new List<SubCategory>();
            List<List<SubCategory>> subCategoriesList = new List<List<SubCategory>>(); 
            List<string> ColumnNamesSubCategory1 = new List<string> { "Group2", "Group2Descr" };
            List<string> ColumnNamesSubCategory2 = new List<string> { "Group3", "Group3Desc" };
            List<int> CorrectColumn1 = new List<int>();
            List<int> CorrectColumn2 = new List<int>();


            for(int i = 0; i < ColumnNamesSubCategory1.Count; i++)
            {
                CorrectColumn1.Add(excellObj.findColumn(ColumnNamesSubCategory1[i]));
                CorrectColumn2.Add(excellObj.findColumn(ColumnNamesSubCategory2[i]));
            }

            for(int i = 1; i < excellObj.allRows; i++)
            {
                subCategories1.Add(subCategory = new SubCategory(excellObj.getValuesFromCell(i, CorrectColumn1[1]),excellObj.getValuesFromCell(i,CorrectColumn1[0]), "Home"));
                subCategories2.Add(subCategory = new SubCategory(excellObj.getValuesFromCell(i,CorrectColumn2[1]), excellObj.getValuesFromCell(i,CorrectColumn2[0]), "Home"));
            }

            subCategoriesList.Add(subCategories1);
            subCategoriesList.Add(subCategories2);


            return subCategoriesList;
        }

        public void finnishedUsingExcel()
        {
            excellObj.CloseApplication();
        }

    }
}

我想要发生的是我想要运行一个

if(categories.Contains(category) == false){
    categories.add(category)
}

我不理解文档中的这一部分?

   public Person(string lastName, string ssn)
   {
      if (Regex.IsMatch(ssn, @"\d{9}"))
        uniqueSsn = $"{ssn.Substring(0, 3)}-{ssn.Substring(3, 2)}-{ssn.Substring(5, 4)}";
      else if (Regex.IsMatch(ssn, @"\d{3}-\d{2}-\d{4}"))
         uniqueSsn = ssn;
      else
         throw new FormatException("The social security number has an invalid format.");

      this.LastName = lastName;
   }

【问题讨论】:

标签: c# list contains


【解决方案1】:

假设你有这样的代码:

List<CustomObject> listOfCustomObjects = new List<CustomObject>();

解决方案 1

如果是这样,您可以使用listOfCustomObjects.Contains(customObject) 来确定@​​987654326@ 是否在listOfCustomObjects 中。您应该在代码顶部添加using System.Linq; 才能使用此方法。

解决方案 2

另一种避免列表中重复的方法基本上是不使用List。您可以改用HashSet。使用此方法,重复的对象不会自动添加到您的列表中。 HashSet 也在 LINQ 库中,因此您也应该为此解决方案添加 using System.Linq; 行。下面是一个示例,如何使用您的 CustomObject 类创建一个新的 HashSet

HashSet<CustomObject> setOfCustomObjects = new HashSet<CustomObject>();

【讨论】:

  • List&lt;&gt; 类已经 implements ICollection&lt;&gt;.Contains() 方法,这就是 Enumerable.Contains() 最终会调用的方法。
  • 但我的代码不会将其视为同一个对象,因为我在我的代码中同时创建了一个新的 Category 对象,不确定这是否会产生错误,正如您在我的代码中看到的那样我已经尝试过 contains 方法,但它只是添加了一个相同的对象
【解决方案2】:

如果这样做是合理的,你真的应该让你的类实现 IEquatable,并且你会以任何频率检查相等性,这样它就不会咬你。 “包含”方法可以工作,但只是为了测试是否存在 exact 相同的实例,不一定是只共享匹配属性的实例。考虑以下代码:

class Program
    {
        static void Main(string[] args)
        {
            var classInstance = new MySampleClass("testA", "testB");

            var classList = new List<MySampleClass>();
            classList.Add(classInstance);

            if (classList.Contains(new MySampleClass("testA", "testB")))
            {
                Console.WriteLine("true");
            }
            else
            {
                Console.WriteLine("false");
            }

            if (classList.Contains(classInstance))
            {
                Console.WriteLine("true");
            }
            else
            {
                Console.WriteLine("false");
            }
        }
    }

    public class MySampleClass
    {
        public string SampleProperty1 { get; set; }
        public string SampleProperty2 { get; set; }

        public MySampleClass(string sampleProperty1, string sampleProperty2)
        {
            SampleProperty1 = sampleProperty1;
            SampleProperty2 = sampleProperty2;
        }
    }

即使我们正在检查是否存在与我们之前添加的值完全相同的类,它们仍然是单独的实例,并且您最终会在列表中找到重复的实例。

在非常有限的情况下,另一种选择是使用 LINQ 方法来检查列表是否已经包含具有 可以比较的属性的条目,例如 int ID 或其他东西:

 yourList.Any(item => item.Id.Equals(otherItem.Id));

同样,如果它不止一次,请使用 IEquatable 以正确的方式实现它。见Microsoft's documentation

【讨论】:

  • 你会说第二种选择是正确的方法还是我理解你错了
  • 我只会使用Any LINQ 方法作为创可贴,如果这是您唯一一次要寻找匹配或相等性,否则我会使用完整的 IEquatable 模式并实现Equals()GetHashCode()。根据文档,除非您添加了逻辑来展示如何为您的自定义类测试它,否则您将永远无法真正有效地检查列表、字典或哈希集中的相等性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-13
  • 2015-05-08
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
  • 1970-01-01
  • 2023-02-25
相关资源
最近更新 更多