C# 如何为集合创建公共 getter 和 setter 以及私有方法?

2024-01-12

我想要一个带有(例如)SortedList 集合“SrtdLst”属性的类“A”,并且在该类“A”内允许添加或减去“SrtdLst”项目。但在“A”类的实例中,只允许获取或设置项目的内容,不允许添加新项目或减去现有项目。在代码中:

class A
{
    public SortedList<string, string> SrtdLst = new SortedList<string, string>();

    public A()
    {
        // This must work:
        SrtdLst.Add("KeyA", "ValueA");
        // This too:
        SrtdLst["KeyA"] = "ValueAAA";
    }
}

class B
{
    public A a = new A();
    public B()
    {
        // I want the following code to fail:
        a.SrtdLst.Add("KeyB", "ValueB");
        // But this must work:
        a.SrtdLst["KeyA"] = "ValueBBB";
   }
}

更新:我想创建一个类似 System.Data.SqlClient.SqlCommand 的类。对于存储过程,您可以使用成员“DeriveParameters”来填充“Parameters”集合,因此只能修改每个项目的值。

如何才能做到这一点?


如果你想在编译时禁止修改操作,你需要一个类型安全的解决方案。

为公共允许的操作声明一个接口。使用该接口作为属性类型。

public interface IReadOnlyList<T>
{
    T this[int index] { get; }

    int Count { get; }
}

然后声明一个实现该接口并继承自标准集合类的类。

public class SafeList<T> : List<T>, IReadOnlyList<T> { }

假设您正确定义了接口,则无需手动实现任何内容,因为基类已经提供了实现。

使用该派生类作为存储属性值的字段的类型。

public class A
{
    private SafeList<string> _list = new SafeList<string>();

    public IReadOnlyList<string>
    {
        get { return _list; }
    }
}

在 A 类中,您可以使用_list直接修改内容即可。 A 类客户端只能使用通过以下方式可用的操作子集IReadOnlyList<T>.

对于您的示例,您使用的是 SortedList 而不是 List,因此接口可能需要

public interface IReadOnlyDictionary<K, V> : IEnumerable<KeyValuePair<K, V>>
{
    V this[K index] { get; }        
}

我也让它继承了 IEnumerable,无论如何它都是只读的,所以是完全安全的。那么安全类将是:

public class SafeSortedList<K, V> : SortedList<K, V>, IReadOnlyDictionary<K, V> { }

但除此之外,都是同样的想法。

更新:只是注意到(由于某种原因我无法理解)你不想禁止修改操作 - 你只是想禁止一些修改操作。很奇怪,但它仍然是相同的解决方案。无论您想要允许什么操作,都可以在界面中“打开它们”:

public interface IReadOnlyDictionary<K, V> : IEnumerable<KeyValuePair<K, V>>
{
    V this[K index] { get; set; }        
}

当然,现在这个接口的名称是错误的...到底为什么您要禁止通过 Add 添加而不是通过索引器禁止它? (索引器可用于添加项目,就像 Add 方法一样。)

Update

根据您的评论,我认为您的意思是您希望允许分配给现有键/值对的值,但不允许分配给以前未知的键。显然,由于键是在运行时由字符串指定的,因此无法在编译时捕获它。所以你不妨进行运行时检查:

public class FixedSizeDictionaryWrapper<TKey, TValue> : IDictionary<TKey, TValue>
{
    IDictionary<TKey, TValue> _realDictionary;

    public FixedSizeDictionaryWrapper(IDictionary<TKey, TValue> realDictionary)
    {
        _realDictionary = realDictionary;
    }

    public TValue this[TKey key]
    {
        get { return _realDictionary[key]; }

        set 
        {
            if (!_realDictionary.Contains(key))
                throw new InvalidOperationException();

            _realDictionary[key] = value;
        }
    }

    // Implement Add so it always throws InvalidOperationException

    // implement all other dictionary methods to forward onto _realDictionary
}

任何时候你有一个普通的字典,并且你想将它交给一些你不信任的方法来更新现有值,请将其包装在其中一个方法中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 如何为集合创建公共 getter 和 setter 以及私有方法? 的相关文章

  • 如何使用 C# 打印 pdf

    我在 C 应用程序中使用 进程 打印 pdf 文件 但是我无法获取打印状态 我发现可以通过 System management 和 System printing 与打印机 队列进行交互 我做了很多尝试 但都出错了使用这两个命名空间但无法打
  • C#9 顶级语句文件上的属性

    我正在尝试向顶级语句文件添加属性 但没有找到任何相关信息 是否可以 对于某些上下文 我想仅在该文件中禁用规则 SuppressMessage StyleCop CSharp LayoutRules SA1516 ElementsMustBe
  • 何时对向量进行归一化?

    我正在学习 XNA 并且在几乎所有的教育套件中都可以找到http creators xna com en US http creators xna com en US 我总是看到向量上对 Normalize 的调用 我知道归一化基本上将向量
  • C++ - 模板专业化和部分专业化

    我一直在互联网和 stackoverflow 上寻找具体的答案 但我似乎找不到 我必须创建一个通用类 然后实现特定的功能 我的具体说明是 您需要使用模板表达式参数以及模板类专业化和部分专业化 我有一个模板类 template
  • 此插件导致 Outlook 启动缓慢

    我正在使用 C NET 4 5 开发 Outlook Addin 项目 但部署后 有时 Outlook 会禁用我的插件 并显示此消息 这个插件导致 Outlook 启动缓慢 我不知道我的插件出了什么问题 这只有很少的代码 并且ThisAdd
  • 将占位符文本添加到文本框

    我正在寻找一种将占位符文本添加到文本框的方法 就像在 html5 中使用文本框一样 IE 如果文本框没有文本 则会添加文本Enter some text here 当用户单击它时 占位符文本消失并允许用户输入自己的文本 如果文本框失去焦点并
  • 实体框架7审计日志

    我正在将一个旧项目移植到 ASP NET 5 和 Entity Framework 7 我使用数据库优先方法 DNX 脚手架 来创建模型 旧项目基于Entity Framework 4 审计跟踪是通过重写实现的SaveChanges的方法D
  • 未定义异常变量时通过引用捕获

    捕获异常时 标准指导是按值抛出 按引用捕获 据我了解 这有两个原因 如果由于内存不足异常而引发异常 我们将不会调用可能终止程序的复制构造函数 如果异常是继承层次结构的一部分 我们可能会对异常进行对象切片 如果我们有一个场景 我们没有在 ca
  • 首先EntityFramework数据库 - 类型映射 - 将binary(8)从SQL映射到C#中的int

    在 SQL 内部 我有一个主键为二进制 8 的表 当我使用该表添加到我的模型中时Update Model from Database我可以看到该列有 type Binary 在 C 中 我将该列设为byte 我可以将该列映射到 int 吗
  • C++ 析构函数:何时释放内存?

    如果我删除一个导致其析构函数被调用的对象 那么内存是在析构函数完成函数中的任何操作之前还是之后被释放 仅当最小派生类子对象被销毁后才会释放内存 所以如果你有 class Base class Derived public Base publ
  • ASP MVC 5 - 403 customError 不起作用

    我正在尝试为我的应用程序创建自定义错误页面 它在大部分情况下都有效 但不适用于403 errors 我的网络配置
  • 使用对象列表构建树

    我有一个带有属性 id 和parent id 的对象列表 我想建造一棵树来连接那些孩子和父母 1 个父对象可以有多个子对象 并且有一个对象将成为所有对象的祖先 实现该功能最快的算法是什么 我使用 C 作为编程语言 但其他语言也可以 像这样的
  • 为什么在 .net 中使用 Invoke on Controls? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么 NET不允许跨线程操作 https stackoverflow com questions 2896504 why net does not allow cross thread operat
  • 为什么 GCC 6.3 在没有显式 C++11 支持的情况下编译此 Braced-Init-List 代码?

    我有一个问题大括号括起来的列表的不同含义 https stackoverflow com q 37682392 2642059 我知道C 03不支持C 11initializer list 然而 即使没有 std c 11编译器标志 gcc
  • 函数模板重载解析期间的 MSVC 与 Clang/GCC 错误,其中一个函数模板包含参数包

    当我使用参数包时 我注意到这样一种情况 如下所示 在 gcc 和 clang 中编译得很好 但在 msvc 中却不行 template
  • 语义问题 Qt Creator:命名空间“std”中没有名为“cout”的成员

    我开始使用 Qt Creator 编写代码 对于 C 文件 我遇到很多语义问题 99 是 命名空间 yyy 中没有名为 xxx 的成员cpp文件构建 编译和输出没有问题 如果我点击例如cout 我已链接到 iostream 我是否需要在 Q
  • Unity 2.0 和处理 IDisposable 类型(特别是使用 PerThreadLifetimeManager)

    我知道类似的问题被问过好几次 例如 here https stackoverflow com questions 987761 how do you reconcile idisposable and ioc here https stac
  • 统一;随机物体移动[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在制作一款机器人战斗游戏 我希望敌人随机移动 然后有时会向敌人移动 我希望运动包含在其中的代码 else if avoid fal
  • Visual Studio 2015默认附加库

    当我在 VS 2015 中创建一个空项目时 它会自动将这些库放入 附加依赖项 中 kernel32 lib user32 lib gdi32 lib winspool lib comdlg32 lib advapi32 lib shell3
  • Crypto++ 和压缩 EC 密钥

    如何在 Crypto 中生成压缩的 ECDSA 密钥 AutoSeededRandomPool prng ECDSA

随机推荐

  • 将字符添加到频率列表

    我有一个关于霍夫曼编码的项目 但我陷入困境 我不明白为什么我的代码不起作用 这是练习 写一个函数add1给定一个字符 它在频率列表中的频率加 1 如果该字符尚未出现在频率列表中 则会添加该字符 add1 e l 1 e 2 x 1 l 1
  • 连接到 SQL Server 时出现 SQL 异常

    我知道这是一个重复的问题 我发现了非常相似的问题和解决方案 但仍然让我震惊 我正在使用 eclipse 将我的 java 应用程序与 microsoft sql server 2008 数据库连接 以下是我的代码 import java s
  • 使用 JPQL 过滤具有唯一 ID 的重复记录

    我正在查询一个维护不善的建筑物数据库 其记录类似于以下内容 ID NAME CODE 54 Building A a1234 97 Building A a1234 我正在使用以下 JPQL 语句进行查询 其中 bCodes 是建筑代码数组
  • 如何检测Android H.264硬件加速能力

    大量 但不是全部 Android 设备支持 H 264 视频编解码器的硬件加速 但不支持 VP8 VP9 编解码器 为了提供更高质量的用户体验 我们希望尽可能选择硬件加速的编解码器 因此 需要运行时检测特定设备是否具有 H 264 硬件加速
  • 如何将 JSON 转换为数组并在 jQuery 中循环遍历它?

    我正在使用 JSON 与用户进行通信 PHP 将数组转换为 JSON 的形式如下 success text to display warning NONE notice text to display error NONE jQuery 显
  • OS X Dock API?检索 OS X 活动应用程序的图标以及徽章和其他修改

    是否有 API 用于检索 Mac OS X 上当前打开的应用程序的图标 我正在尝试检索活动应用程序的所有图标以及应用程序顶部的任何徽章 即邮件中的新消息数量或传输中的当前下载速率 有某种 Dock API 吗 我能找到的唯一提到用于检索当前
  • Chrome 中的默认输入边框

    默认情况下 输入元素的样式为border 2px inset 但是 只要背景是白色 边框就会显示为细灰色线 带有 eee颜色 但如果我改变背景 即使是最轻微的 例如 feffff 边界突然改变为你所期望的2px inset 是什么导致了这种
  • 将十六进制字符串转换(解码)为 ASCII 或任何其他可理解的格式 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 b 7668647866696c654d006900630072006f0073006f00660074002000570069006e00
  • 我如何让 Eclipse 将 .ejs 文件解释为 .html?

    我最近开始了一个节点项目 我使用的两个模块是express和EJS 但默认情况下我通常使用 eclipse 作为我的 IDE 它对于 java 运行良好 对于 html 和 javascript 也很不错 但我遇到的一个问题是 对于 ejs
  • 在 Vim 中打开特定文件的快捷方式?

    有没有办法在我的系统中配置快捷方式 vimrc自动在新缓冲区中打开特定文件 我有一个经常需要访问的文件 我想在编码或写入会话期间在新缓冲区中快速打开该文件 我并不是在寻找可以使用 Command T 或 PeepOpen 实现的模糊搜索 而
  • Android 发送包含 PDF 文件的邮件

    我正在尝试发送位于设备上文件夹中的 PDF 文件 文件已选择并发送 但它是空的 我哪里错了 String inviare n fr getText toString Uri uri Uri fromFile new File Environ
  • 如何在数据表中创建可水平滚动的单元格

    这是 PrimeFaces 的情况 但我认为这个问题同样适用于标准 JSF 数据表 我有一个数据表列 其中的条目被自动换行 因为内容可能很长 为了使显示更具可读性 我希望内容不被换行 而是提供水平滚动来查看默认情况下不显示的任何内容 我确信
  • Gson 中的 Stackoverflow 异常

    我正在尝试使用 Gson 库将 Json 字符串解析为 Java 对象 但遇到了 StackoverflowException java lang StackOverflowError com google gson internal Gs
  • 将NodaTime转换为Unix时间戳以及LocalDateTime的重要性

    我目前正在使用 NodaTime 因为我对 C 中的时区处理感到沮丧DateTime班级 到目前为止 我真的很高兴 public static string nodaTimeTest string input var defaultValu
  • AWS SageMaker - 在本地训练但部署到 AWS?

    我在使用 SageMaker 时面临以下挑战 我已经下载了一本教程笔记本 https github com awslabs amazon sagemaker examples blob master sagemaker python sdk
  • Json 解析器捕获 Java 中的尾随逗号?

    我使用以下命令来检查 json 文件是否有效 JsonParser parser new JsonParser parser parse new String Files readAllBytes Paths get filePath to
  • 是否有干净的方法将上下文数据传递给 @Asynchronous ejb 调用?

    在 Wildfly 中 我异步执行无状态 ejb 方法 它使用 Asynchronous 注释进行映射 在调用方法中 我在线程本地有一些上下文信息 将此数据传递给异步方法的最佳方法是什么 我不想向异步方法签名添加额外的参数 本质上你只有两个
  • 使用 SqlMembershipProvider 禁用帐户锁定

    如何禁用账户锁定功能SqlMembershipProvider MSDN 文档的最大无效密码尝试次数 http msdn microsoft com en us library system web security membership
  • Python - 比 2 个嵌套 for 循环更快的东西

    def fancymatching fname1 fname2 This function will do much smarter and fancy kinds of compares if fname1 fname2 return 1
  • C# 如何为集合创建公共 getter 和 setter 以及私有方法?

    我想要一个带有 例如 SortedList 集合 SrtdLst 属性的类 A 并且在该类 A 内允许添加或减去 SrtdLst 项目 但在 A 类的实例中 只允许获取或设置项目的内容 不允许添加新项目或减去现有项目 在代码中 class