Reputation: 10152
I'm using FileSystemWatcher class to monitor a folder and update the list as events arise. I'm using the following class to hold information for each file:
public class FileItem
{
public string Name { get; set; }
public string Path { get; set; }
}
The following list holds the collection of that information:
public static List<FileItem> folder = new List<FileItem>();
I added some FileItem objects into the list. However, to remove a specific item that has a matching name, I couldn't just use foreach() loop because enumerations change and as soon as the file is removed, I get an exception. So, I added a break (since there will only be one file with the same name) to break out of the foreach() loop after an item was removed... but I'm not sure if it's the most efficient way to do it. Is there a simpler and more appropriate way? Here's my code for the removal:
private static void OnChanged(object source, FileSystemArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Deleted)
{
foreach (var item in folder)
{
if (item.Name == e.Name)
{
folder.Remove(item);
folder.TrimExcess();
break;
}
}
}
}
Upvotes: 2
Views: 2752
Reputation: 3403
you can remove any item by populating it through linq and then removing it from the list
List<FileItem> folder = new List<FileItem>();
folder.Remove(folder.SingleOrDefault(x=>x.Name == "myname"));
folder.Remove(folder.SingleOrDefault(x => x.Path == "mypath"));
Upvotes: 7
Reputation: 48568
How about
private static void OnChanged(object source, FileSystemArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Deleted)
{
FileItem item = folder.SingleOrDefault(x => x.Name == e.Name);
if (item != null)
folder.Remove(item);
}
}
Upvotes: 2
Reputation: 29981
If you can restructure your data, here is a Dictionary<>
based approach:
// let the key be Name, and value be Path.
public static Dictionary<string, string> folder = new Dictionary<string, string>();
private static void OnChanged(object source, FileSystemArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Deleted)
{
folder.Remove(e.Name);
}
}
This will be much more performant as the size of folder
increases, because Dictionary<>
operations are amortized O(1) while List<>.Remove
is O(n).
This also explicitly enforces your contract of "there will only be one file with the same name", as that is a basic property of Dictionary<>
.
You might want to pass in StringComparer.InvariantIgnoreCase
to the dictionary's constructor, as file names are case-insensitive on Windows. This is platform-dependent -- Linux is case-sensitive -- so if you're making a shared library that needs to be robust and cross-platform, you'll want to figure out a way to select the correct comparer. This issue affects all answers, not just mine.
Upvotes: 1
Reputation: 629
You can try using a for loop
for(int x = folder.Count() - 1; x>=0; x--)
{
if (folder[x].Name == e.Name)
{
folder.Remove(folder[x]);
}
}
Upvotes: 1