0
public struct RegistryApp
{
    public string VendorName;
    public string Name;
    public string Version;
} 

我有两个List<RegistryApp>,其中包含当前安装在 Windows 框中的所有应用程序。为什么是两个?好吧,我有一个列表来保存所有x86应用程序,一个列表来保存所有应用x64程序。

List<RegistryApp> x64Apps64List = new List<RegistryApp>();
List<RegistryApp> x64Apps32List = new List<RegistryApp>();

一旦这两个填充了从注册表中检索到的相应数据,我会尝试以下操作以确保没有重复项。这工作得体,List<string>但不适用于List<RegistryApp>.

List<RegistryApp> ListOfAllAppsInstalled = new List<RegistryApp>();

IEnumerable<RegistryApp> x86Apps = x64Apps32List.Except(x64Apps64List);
IEnumerable<RegistryApp> x64Apps = x64Apps64List.Except(x64Apps32List);

foreach (RegistryApp regitem in x86Apps)
{
    if ((regitem.Name != null) && 
     (regitem.Name.Length > 2) && 
     (regitem.Name != "")) 
    {
        ListOfAllAppsInstalled.Add(regitem);
    }
}

foreach (RegistryApp regitem in x64Apps) 
{
    if ((regitem.Name != null) && 
     (regitem.Name.Length > 2) && 
     (regitem.Name != "")) 
    {
        ListOfAllAppsInstalled.Add(regitem);
    }
}

有什么办法可以解决这个问题吗?

4

2 回答 2

5

已编辑

要从存在于另一个列表中的结构列表中删除项目,您可以查看Cuong LeHere 提供的解决方案:

https://stackoverflow.com/a/12784937/1507182

通过在 List 类型上使用 Distinct 无参数扩展方法,我们可以删除那些重复的元素。

然后,我们可以选择调用 ToList 扩展来获取删除重复项的实际列表。

static void Main()
    {
    // List with duplicate elements.
    List<int> mylist = new List<int>();
    mylist.Add(1);
    mylist.Add(2);
    mylist.Add(3);
    mylist.Add(3);
    mylist.Add(4);
    mylist.Add(4);
    mylist.Add(4);

    foreach (int value in mylist)
    {
        Console.WriteLine("Before: {0}", value);
    }

    // Get distinct elements and convert into a list again.
    List<int> distinct = mylist.Distinct().ToList();

    foreach (int value in distinct)
    {
        Console.WriteLine("After: {0}", value);
    }
    }

如果我的回答解决了您的问题,请单击接受为解决方案按钮,这样做将帮助其他人知道解决方案。

于 2013-05-05T00:51:33.377 回答
2

为了让 Execpt工作,你使用它的东西必须是可比较的。要使其适用于您的自定义结构,您需要执行以下两项操作之一,即覆盖GetHashCodeEquals以便能够Execpt 与您的结构一起使用:

public struct RegistryApp
{
    public string VendorName;
    public string Name;
    public string Version;

    public override bool Equals(object obj) 
    {
       if (!(obj is MyStruct))
          return false;

       RegistryApp ra = (RegistryApp) obj;

       return ra.VendorName == this.VendorName &&
              ra.Name == this.Name &&
              ra.Version == this.Version;

    }

    public override int GetHashCode()
    {
        return VendorName.GetHashCode() ^ Name.GetHashCode() ^ Version.GetHashCode();
    }

} 

或使用Execpt 的重载,它允许您传入自己的比较器并将其传入。有关示例,请参见 MSDN

于 2013-05-05T01:24:17.313 回答