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

I Have two List<RegistryApp> which hold all Applications currently installed on the Windows box. Why two? Well I have one List to hold all x86 Applications and one to hold all x64 Applications.

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

Once those two are populated with their appropriate data which was retrieved from the registry, I try the following to make sure there are no duplicates. This worked decently on List<string> but not working with 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);
    }
}

Any way to pull this off?

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
Dayan
  • 7,634
  • 11
  • 49
  • 76

2 Answers2

5

EDITED

To remove items from a List of Structs that exist in another List you can see the solution provided by Cuong Le Here :

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

By using the Distinct parameterless extension method on the List type, we can remove those duplicate elements.

Then, we can optionally invoke the ToList extension to get an actual List with the duplicates removed.

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);
    }
    }

If my answer has solved your problem click Accept as solution button, doing it will help others know the solution.

Community
  • 1
  • 1
Obama
  • 2,586
  • 2
  • 30
  • 49
2

For Execpt to work the thing you are using it on must be compareable. To make it work for your custom struct you will need to do one of two things, either override GetHashCode and Equals to be able to use Execpt with your struct:

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();
    }

} 

or use the overload of Execpt that allows you to pass in your own comparer and pass that in. See the MSDN for an example

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • I see why I was given a -1 now, I have fixed the wording. – Scott Chamberlain May 05 '13 at 01:28
  • This looks like it would work but I was not able to get it working, I tested out Obamas code and it worked, i did have to make some changes: `List UniqueEntries = ListOfAllAppsInstalled.Distinct().ToList();` – Dayan May 05 '13 at 02:16