views:

458

answers:

2

First of all, it very well could be that I'm approaching my problem the wrong way, in which case I'd gladly accept alternatives.

What I'm trying to achieve is to detect which drive was created after a USB device has been connected to a computer.

Here is the simplified workflow:

// Get list of removable drives before user connects the USB cable
List<string> listRemovableDrivesBefore = GetRemovableDriveList();

// Tell user to connect USB cable
...

// Start listening for a connection of a USB device
...

// Loop until device is connected or time runs out
do
{
    ...
} while

// Get list of removable drives after USB device is connected
List<string> listRemovableDrivesAfter = GetRemovableDriveList();

// Find out which drive was created after USB has been connected
???

GetRemovableDriveList returns a list of strings of the removable drive letters. My idea was to get a list of removable drives before the device is connected, and another list after it is connected, and that by removing the contents of the first list from the second, I would be left with drives that were just connected (normally only one).

But I can't find a simple way of "subtracting" one list from another. Anyone could suggest a solution, or even a better way of achieving what I'm trying to do.

Note: project is targeting the .NET framework 2.0, so no LINQ possible.

Thanks!

+1  A: 

For a small number of elements then a foreach loop with a Contains call should do the trick:

List<string> listRemovableDrivesBefore = GetRemovableDriveList();
// ...
List<string> listRemovableDrivesAfter = GetRemovableDriveList();

List<string> addedDrives = new List<string>();
foreach (string s in listRemovableDrivesAfter)
{
    if (!listRemovableDrivesBefore.Contains(s))
        addedDrives.Add(s);
}

If the collection has many elements then you could make the lookups more efficient by using a Dictionary<K,V> rather than a List<T>. (Ideally you'd use a HashSet<T>, but that's not available in version 2 of the framework.)

LukeH
I chose this answer because I needed a one-time thing. If I had needed to do this repeatedly and at different places, I would probably have implemented the Subtract from Lee's answer.
Fueled
+1  A: 

A general way to do this would be to add all the items from the source collection to a dictionary and then remove items in the other collection:

public static IEnumerable<T> Subtract<T>(IEnumerable<T> source, IEnumerable<T> other)
{
    return Intersect(source, other, EqualityComparer<T>.Default);
}

public static IEnumerable<T> Subtract<T>(IEnumerable<T> source, IEnumerable<T> other, IEqualityComparer<T> comp)
{
    Dictionary<T, object> dict = new Dictionary<T, object>(comp);
    foreach(T item in source)
    {
        dict[item] = null;
    }

    foreach(T item in other)
    {
        dict.Remove(item);
    }

    return dict.Keys;
}
Lee
An efficient solution, but the method is mis-named. It doesn't return the intersection of the two sequences.
LukeH
In my mind both answer are valid, but because of my requirement, I chose the easy way.
Fueled