如何保护访问者只有IEnumerable <string>属性才能发生变异?

Kar*_*son 2 c# generics ienumerable

假设我有这个:

public class MyClass
{
    private readonly List<string> _strings = new List<string>();

    public IEnumerable<string> MyStrings 
    { 
        get 
        { 
            return _strings; 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何防止以下实际添加到字符串的成员变量列表?

var theClass = new MyClass();
((List<string>)theClass.MyStrings).Add("I do not want to be able to add this!");
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 8

创建一个"包装"序列的新类型.虽然有很多方法可以做到这一点,但一个相当简单的"hack"就是Select在身份转换上使用它:

return _strings.Select(x=>x); 
Run Code Online (Sandbox Code Playgroud)

这将使用它自己的迭代器创建一个新对象,该迭代器在内部具有对_strings列表的引用.由于额外的间接层(并且该类型的额外奖励是语言内部的类型,无法在语言定义之外使用),调用者无法再将其传播到列表中.

如果你想要一些更清晰的东西来阅读,使意图更加为人所知,你可以为它做一个新的方法:

public static IEnumerable<T> AsSequence<T>(this IEnumerable<T> sequence)
{
    return sequence.Select(x => x);
}
Run Code Online (Sandbox Code Playgroud)

(请随意将其命名为最清楚的.)