我具有以下属性:

private static Collection<Assembly> _loadedAssemblies = new Collection<Assembly>();
    internal static ReadOnlyCollection<Assembly> LoadedAssemblies
    {
        get { return new ReadOnlyCollection<Assembly>(_loadedAssemblies); }
    }


在另一个类中,我遍历LoadedAssemblies

foreach (Assembly assembly in ResourceLoader.LoadedAssemblies)


在遍历程序集时,基础集合(_loadedAssemblies)有时会更改,从而给出System.InvalidOperationException。使LoadedAssemblies安全的首选方法是什么?我无法重现该问题,所以我不能只是尝试一下。

可以吗?

internal static ReadOnlyCollection<Assembly> LoadedAssemblies
    {
        get { return new ReadOnlyCollection<Assembly>(_loadedAssemblies.ToList()); }
    }


编辑

    public static void Initialize()
    {

        foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            AddAssembly(assembly);
        }
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyLoad += OnAssemblyLoad;
    }

    private static void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
    {
        AddAssembly(args.LoadedAssembly);
    }

    private static void AddAssembly(Assembly assembly)
    {
        AssemblyName assemblyName = new AssemblyName(assembly.FullName);
        string moduleName = assemblyName.Name;

        if (!_doesNotEndWith.Exists(x => moduleName.EndsWith(x, StringComparison.OrdinalIgnoreCase)) &&
            _startsWith.Exists(x => moduleName.StartsWith(x, StringComparison.OrdinalIgnoreCase)))
        {
            if (!_loadedAssemblies.Contains(assembly))
            {
                _loadedAssemblies.Add(assembly);
            }
        }
    }

最佳答案

您的问题中的建议将起作用。那是:

internal static ReadOnlyCollection<Assembly> LoadedAssemblies
{
    get { return new ReadOnlyCollection<Assembly>(_loadedAssemblies.ToList()); }
}


原因是您的问题来自_loadedAssemblies进行枚举时被更改。当然会发生这种情况,因为ReadOnlyCollection只是_loadedAssemblies的包装,该包装使用基集合的枚举器。

如果您执行_loadedAssemblies.ToList(),则这将创建一个新列表,该列表是原始_loadedAssemblies的副本。它在创建时将具有所有相同的元素,但将永远不会再次更新(因为您甚至没有对新集合的引用,因此无法对其进行修改)。这意味着,当更新_loadedAssemblies时,ReadOnlyCollection中的新列表将非常高兴地不知道该更改,因此您的枚举将毫无问题地继续进行到最后。

关于c# - 迭代时修改了Collection的ReadOnlyCollection属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45688470/

10-10 10:00