防止添加到公共字典

Mos*_*aou 1 c#

我在公共课堂上有一个公共字典如下:

namespace ApiAssembly
{
    public static class TypeStore
    {
        /// <summary>
        /// Initializes static members of the <see cref="TypeStore"/> class.
        /// </summary>
        static TypeStore()
        {
            Store = new Dictionary<string, Type>();
        }

        /// <summary>
        /// Gets the store.
        /// </summary>
        public static Dictionary<string, Type> Store { get; }

        public void AddTypes()
        {
            // This should be allowed
            TypeStore.Store.Add("object", typeof(object));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想阻止在内部添加新元素(通过API管理).实现这一目标的最佳方法是什么?

namespace ClientAssembly
{
    using ApiAssembly;

    public class Client
    {
        public void AddTypes()
        {
            // How to prevent this call?
            TypeStore.Store.Add("object", typeof(object));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Dictionnary的内容必须是可公开访问的,因此只需翻转访问修饰符就不是一种选择

Pat*_*man 7

您应该将实际存储字典与您用于外部世界的字典分开.一个简单的方法是:

private static Dictionary<string, Type> Storage { get; } = new Dictionary<string, Type>();

public static ReadOnlyDictionary<string, Type> Store 
              => new ReadOnlyDictionary<string, Type>(Storage);
Run Code Online (Sandbox Code Playgroud)

Storage您可以编辑的实际支持字典在哪里.

或者甚至更好,通过您的类(它充当代理)公开您想要的方法,在这里您永远不会授予外部类访问字典本身的权限.


are*_*yla 5

将其公开为:

IReadOnlyDictionary<string, Type> dictionary = new Dictionary<string, Type>();
Run Code Online (Sandbox Code Playgroud)

或者另外使用ReadOnlyDictionary包装纸以防止回流Dictionary.

完整示例:

public static class TypeStore
{
    private static Dictionary<string, Type> store;

    private static ReadOnlyDictionary<string, Type> storeReadOnly ;

    /// <summary>
    /// Initializes static members of the <see cref="TypeStore"/> class.
    /// </summary>
    static TypeStore()
    {
        store = new Dictionary<string, Type>();
        storeReadOnly = new ReadOnlyDictionary<string, Type>(store);
    }

    /// <summary>
    /// Gets the store.
    /// </summary>
    public static IReadOnlyDictionary<string, Type> Store => storeReadOnly;

    public static void AddTypes()
    {
        // This should be allowed
        TypeStore.store.Add("object", typeof(object));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Rawling如果你担心恶意用户有意访问他们知道他们不应该访问的实现细节,那么即使`ReadOnly Dictionary`也无济于事,因为他们仍然可以从中获取私有财产并使用它.如果您认为您的方法的调用方故意试图违反您的API,那么您无法阻止它们,因此考虑此类用户并不是真正有意义的.如果您认为用户没有故意违反您的API,那么界面就可以正常工作了. (3认同)
  • 最好将它包装在一个`new ReadOnlyDictionary(...)`中,这样它们就不能再将其强制转换. (2认同)