C#中如何禁止直接操作私有set的List,强制使用指定添加方法
解决方法:限制外部直接修改Errors列表
这个问题其实很常见——你虽然把Errors的setter设为private,但List<string>本身是可变引用类型,外部拿到这个列表的引用后,依然可以调用它的Add、Remove等修改方法,完全绕开了你写的AddError逻辑。要解决这个问题,核心是不让外部拿到可变列表的直接引用,而是暴露只读的接口或包装类型。
下面给你两种可行的方案:
方案1:将Errors的公开类型改为IEnumerable
把内部维护的可变列表和对外暴露的接口分开,内部用List<string>存储,对外只暴露IEnumerable<string>(它没有修改集合的方法):
public class PaginationReturn<T> { // 内部私有的可变列表,仅类内部可以修改 private readonly List<string> _errors; public PaginationReturn() { _errors = new List<string>(); Success = true; } public IEnumerable<T> Data { get; set; } public bool Success { get; private set; } // 对外暴露只读的枚举接口,只能遍历,不能修改 public IEnumerable<string> Errors => _errors; public void AddError(string mensagem) { _errors.Add(mensagem); Success = false; } }
这样外部代码调用paginationReturn.Errors.Add("Error!!")会直接编译报错,因为IEnumerable<string>没有Add方法,必须通过AddError来添加错误信息。
方案2:返回ReadOnlyCollection(更安全的选择)
如果想更明确地阻止外部修改,甚至杜绝强制类型转换后的恶意修改,可以用ReadOnlyCollection<string>包装内部列表:
public class PaginationReturn<T> { private readonly List<string> _errors; public PaginationReturn() { _errors = new List<string>(); Success = true; } public IEnumerable<T> Data { get; set; } public bool Success { get; private set; } // 对外返回只读包装,任何修改操作都会抛出异常 public ReadOnlyCollection<string> Errors => _errors.AsReadOnly(); public void AddError(string mensagem) { _errors.Add(mensagem); Success = false; } }
这种方案下,即使外部尝试把Errors强制转换为List<string>,调用Add时也会抛出NotSupportedException,彻底阻断了直接修改的可能,同时保留了遍历错误信息的能力。
两种方案都能满足你的需求,你可以根据实际场景选择:如果只是想规范正常使用,方案1足够简洁;如果需要严格防止任何形式的修改,方案2更稳妥。
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

