在c#中是否可以将数组声明为只读?

5

是否可以将一个数组设置为只读,以使对该数组的赋值不被允许。

我尝试使用readonly关键字来声明数组,然后通过使用IsReadOnly属性来检查该数组是否为只读。但它从来没有返回过true。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PrivateExposeConsoleApp
{
    class Program
    {
        private static readonly int[] arr = new int[3] { 1,2,3 };

        static void Main(string[] args)
        {
            // Create a read-only IList wrapper around the array.
            IList<int> myList = Array.AsReadOnly(arr);

            try
            {
                // Attempt to change a value of array through the wrapper. 
                arr[2] = 100;
                Console.WriteLine("Array Elements");
                foreach (int i in arr)
                {
                    Console.WriteLine("{0} - {1}", i + "->", i);
                }
                Console.WriteLine("---------------");
                Console.WriteLine("List Elements");
                foreach (int j in myList)
                {
                    Console.WriteLine("{0} - {1}", j + "->", j);
                }
                // Attempt to change a value of list through the wrapper. 
                myList[3] = 50;
            }
            catch (NotSupportedException e)
            {

                Console.WriteLine("{0} - {1}", e.GetType(), e.Message);
                Console.WriteLine();
            }



            //if (arr.IsReadOnly)
            //{
            //    Console.WriteLine("array is readonly");
            //}
            //else
            //{
            //    for (int i = 0; i < arr.Length; i++)
            //    {
            //        arr[i] = i + 1;
            //    }

            //    foreach (int i in arr)
            //    {
            //        Console.WriteLine(i);
            //    }
            //}

            Console.ReadKey();
        }
    }
}

下面是我的注释部分。如果我取消注释,我的数组将永远不会变得只读。在声明时,我明确将arr定义为只读,数据为{1,2,3}。我不希望这个值被重写。它应该始终是1、2、3。


1
http://msdn.microsoft.com/en-us/library/53kysx7b(v=vs.110).aspx - Lee Taylor
2个回答

6

数组本质上是可变的,为了得到你想要的行为,你需要使用包装器ReadOnlyCollection<T>。你可以使用arr.AsReadOnly()创建一个只读复制的数组。


嗨。我只想让这个数组(在这里是arr)变成只读。这可能吗?arr.AsReadOnly()将返回一个ReadOnlyCollection<T>。那很好,但那不是我的数组。那是另一个对象。 - Chandan Kumar
2
+1. @kumarch1 - 除了“数组本质上是可变的”之外,您还需要什么其他信息?在 .Net 中根本就没有“只读数组”的概念。 - Alexei Levenkov

4

数组类本身定义了Array.AsReadOnly<T>(T[] array)方法,该方法用于将数组设为只读。

该方法接受一个数组作为参数(即要设置为只读的数组),并返回一个ReadOnlyCollection<T>

以下是一个示例:

// declaration of a normal example array
string[] myArray = new string[] { "StackOverflow", "SuperUser", "MetaStackOverflow" };

// declaration of a new ReadOnlyCollection whose elements are of type string
// the string array is passed through the constructor
// that's is where our array is passed into its new casing
// as a matter of fact, the ReadOnlyCollection is a wrapper for ordinary collection classes such as arrays
ReadOnlyCollection<string> myReadOnlyCollection = new ReadOnlyCollection<string>(maArray);

Console.WriteLine(myReadOnlyCollection[0]); // would work fine since the collection is read-only
Console.WriteLine(myReadOnlyCollection[1]); // would work fine since the collection is read-only
Console.WriteLine(myReadOnlyCollection[2]); // would work fine since the collection is read-only

myReadOnlyCollection[0] = "ServerFault"; // the [] accessor is neither defined nor would it be allowed since the collection is read-only.

这里 可以找到相应的MSDN文档。


或者,您可以简单地定义一个getter方法,例如:

public T getElement(int index) { return array[index]; }

如何使你的数组至少从其类的外部来看是只读的?


关于你使用Array.IsReadOnly,MSDN文档说明如下:

对于所有数组,此属性始终为false。

这意味着你必须使用IList<T>.IsReadOnly而不是arr.IsReadOnly。

参见这里


你好,谢谢。你能否举个例子详细说明一下吗?我只是不想让这个被允许。for (int i = 0; i < arr.Length; i++) { arr[i] = i + 1; } - Chandan Kumar
你到底想要实现什么? - marc wellman
请注意,通过迭代这个的速度几乎比迭代数组慢了十倍。 - Mike-E

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接