2

FileSystemWatcher クラスを使用してフォルダーを監視し、イベントが発生したときにリストを更新しています。次のクラスを使用して、各ファイルの情報を保持しています。

public class FileItem
{
    public string Name { get; set; }
    public string Path { get; set; }
}

次のリストには、その情報のコレクションが含まれています。

public static List<FileItem> folder = new List<FileItem>();

リストにいくつかの FileItem オブジェクトを追加しました。ただし、一致する名前を持つ特定のアイテムを削除するには、列挙が変更され、ファイルが削除されるとすぐに例外が発生するため、 foreach() ループを使用することはできませんでした。そこで、項目が削除された後に foreach() ループから抜け出すために (同じ名前のファイルが 1 つしかないため) ブレークを追加しました... しかし、それが最も効率的な方法かどうかはわかりませんそれ。もっと簡単で適切な方法はありますか?削除するための私のコードは次のとおりです。

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

4 に答える 4

6

linqを介してアイテムを入力し、リストから削除することで、アイテムを削除できます

List<FileItem> folder = new List<FileItem>();
folder.Remove(folder.SingleOrDefault(x=>x.Name == "myname"));
folder.Remove(folder.SingleOrDefault(x => x.Path == "mypath"));
于 2013-09-09T01:45:40.670 に答える
2

どうですか

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);
    }
}
于 2013-09-09T01:43:24.447 に答える
1

データを再構築できる場合は、次のDictionary<>ベースのアプローチがあります。

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

folderこれは、のサイズが大きくなるにつれて、はるかにパフォーマンスが向上します。これは、Dictionary<>操作が O(1) で償却されるのに対しList<>.Remove、O(n) であるからです。

これは、の基本的なプロパティであるため、「同じ名前のファイルは 1 つしかない」という契約も明示的に強制しますDictionary<>

StringComparer.InvariantIgnoreCaseWindows ではファイル名の大文字と小文字が区別されないため、辞書のコンストラクターに渡すことができます。これはプラットフォームに依存します。Linux では大文字と小文字が区別されます。そのため、堅牢でクロスプラットフォームである必要がある共有ライブラリを作成している場合は、正しい comparer を選択する方法を見つけ出す必要があります。この問題は、私の回答だけでなく、すべての回答に影響します。

于 2013-09-09T02:49:05.183 に答える
1

for ループを使用してみることができます

for(int x = folder.Count() - 1; x>=0; x--)
{
  if (folder[x].Name == e.Name)
    {
      folder.Remove(folder[x]);
    }
}
于 2013-09-09T01:50:45.410 に答える