C# 公共只读数组数据成员-在类构造函数外部更新

C# 公共只读数组数据成员-在类构造函数外部更新,c#,arrays,readonly,C#,Arrays,Readonly,如果可能的话,请有人告诉我。我正在看微软的XNA框架的GameState代码示例。在其中一个类中,它们使用“公共只读”数组数据成员。虽然不是一种促进OO的实践,但这并没有错 该类后来在构造函数中实例化了它,到目前为止还不错,它的文档也记录在MSDN中 问题:该类稍后在类方法中遍历数组并更改数组中的数据。我查看了MSDN,在谷歌上搜索了一下,我看到的每一个地方都显示它会出错。只读数组是否有特殊的例外情况 请告知 public class InputState { public readon

如果可能的话,请有人告诉我。我正在看微软的XNA框架的GameState代码示例。在其中一个类中,它们使用“公共只读”数组数据成员。虽然不是一种促进OO的实践,但这并没有错

该类后来在构造函数中实例化了它,到目前为止还不错,它的文档也记录在MSDN中

问题:该类稍后在类方法中遍历数组并更改数组中的数据。我查看了MSDN,在谷歌上搜索了一下,我看到的每一个地方都显示它会出错。只读数组是否有特殊的例外情况

请告知

public class InputState
{
    public readonly KeyboardState[] CurrentKeyboardStates;
    public readonly KeyboardState[] LastKeyboardStates;

    public InputState()
    {
        CurrentKeyboardStates = new KeyboardState[max];  
        LastKeyboardStates = new KeyboardState[max];  
    }
    //Does not make sense code...
    public void Update()
    {
        for (int i=0; i < max; ++i)
        {
            //this should throw errors...
            CurrentKeyboardStates[i] = LastKeyboardStates[i];  
            LastKeyboardStates[i] = Keyboard.GetState();
            //more code....
        }
    }
}
公共类InputState
{
公共只读键盘状态[]当前键盘状态;
公共只读键盘状态[]LastKeyboardState;
公共输入状态()
{
CurrentKeyboardState=新键盘状态[max];
LastKeyboardState=新键盘状态[max];
}
//没有意义的代码。。。
公共无效更新()
{
对于(int i=0;i
只读
表示在构造函数中设置变量后,变量无法更改。但是,在本例中,这是对数组对象的引用,可以对其进行更改

如果字段是值类型(例如
int
),则您的理解是正确的。该字段可以由初始值设定项或任何构造函数设置。它与
const
字段几乎相同

但是如果它是一个引用,那么我们所能保证的就是它总是引用同一个对象。是否可以修改该对象取决于其实现。例如,对于数组,可以更改数组的内容,但不能更改其长度

有关详细信息,请参阅MSDN文档

指出将从代码分析生成的警告:。这正是你在这里提出的目的。将数组标记为只读会给您一种无法修改的错误安全感。但是,您唯一不能做的就是为该字段指定一个不同的数组


如果要将信息数组公开给外部,而不改变它,最好的方法是使用
IEnumerable
属性:

public class Foo {
    private int[] _data = new int[40];

    public IEnumerable<int> Data {
        get { return _data; }
    }
}

更改只读数组的元素非常好,只是不能重新分配引用。(无法将CurrentKeyboardState/LastKeyboardState设置为新数组等)可以更改元素值。

与其他两张海报中提到的内容一样,更改所引用的项目没有问题。当引用为只读时,您无法更改它本身


所以你想要的不是一个数组,它是可修改的,而是其他一些一旦定义就不可修改的结构。我不会给您一个完整的解决方案,但您应该查看
IEnumerable
IEnumerator
接口:

好的,我明白了。无法更改/重新分配数组,但可以对其元素进行更改。仅供参考-我确实看过您在回复中链接的示例。它只显示单个值而不是数组,这正是我寻求帮助的原因。再次感谢你,别装出忘恩负义的样子。你做到了。这是否适用于您的解决方案,或者它是否需要像您预期的那样实际上是只读的?对-别担心,我完全理解MSDN文档的不足之处:-)我想我实际上看到了一个实例,其中MSDN上的某些内容与此相关。感谢大家的快速响应。这不是我的代码,只是我正在经历的微软的一个示例项目。我个人不会直接公开数据成员,而是通过属性。对于阵列,我会返回一个克隆,这样我的内部状态就不会被只读关键字的错误安全性搞得一团糟。这实际上并不能解决问题。类的使用者仍然可以将属性强制转换为数组,并可以修改内容。就像我在回答中说的,你需要自己使用接口来实现一些东西。谢谢,我明白了。数组是只读的,这意味着不能重新分配数组,但可以更改元素。@badboy11您正在将接受的答案从一个问题移动到下一个问题。(在3个答案中的每一个上都可以看到。)你只能有1个被接受的答案,但你可以投更多的票。所以选择一个你认为对你帮助最大的对不起,我对投票感到困惑。所有的答案都很好,所以我很难选择一个我觉得最清晰、最简洁的答案,不仅对我来说,而且对将来看到这篇文章的任何人来说都是如此。
Foo f = new Foo();
foreach (int d in f.Data) {
    //...
}

f.Data[0] = 7;           // This won't work. IEnumerable doesn't have [] operator.
f.Data = new int[10];    // This won't work. Data only has a getter.