gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 13:18:28 24 4
gpt4 key购买 nike

我想要一个带有(例如)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”,因此只能修改每个项目的值。

如何做到这一点?

最佳答案

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

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

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

int Count { get; }
}

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

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

假设您获得了正确的接口(interface)定义,您将不需要手动实现任何东西,因为基类已经提供了实现。

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

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

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

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

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

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

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

更新

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

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
}

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

关于C# 如何为集合创建公共(public) getter 和 setter 以及私有(private)方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1080644/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com