コンパイラ エラー CS1656

更新 : 2007 年 11 月

エラー メッセージ

'読み取り専用の変数型' なので '変数' に割り当てできません。

このエラーは、変数に対する値の代入が、読み取り専用のコンテキストで行われた場合に発生します。読み取り専用になるコンテキストとしては、foreach の反復子、using の変数、fixed の変数などがあります。このエラーを解決するには、using ブロック、foreach ステートメント、fixed ステートメントの変数に値が代入されている箇所を修正します。

使用例

次の例では、foreach ループの中にあるコレクションの要素全体を置き換えようとするために、エラー CS1656 が生成されます。このエラーに対処する方法の 1 つは、foreach ループを for ループに変更することです。ここには示されていませんが、もう 1 つの方法として、既存の要素のメンバを変更する方法もあります。これはクラスの場合は可能ですが、構造体の場合は使用できません。

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

namespace CS1654_2
{

    class Book
    {
        public string Title;
        public string Author;
        public double Price;
        public Book(string t, string a, double p)
        {
            Title=t;
            Author=a;
            Price=p;

        }
    }

    class Program
    {
        private List<Book> list;
        static void Main(string[] args)
        {
            Program prog = new Program();
            prog.list = new List<Book>();
            prog.list.Add(new Book ("The C# Programming Language",
                                    "Hejlsberg, Wiltamuth, Golde",
                                     29.95));
            prog.list.Add(new Book ("The C++ Programming Language",
                                    "Stroustrup",
                                     29.95));
            prog.list.Add(new Book ("The C Programming Language",
                                    "Kernighan, Ritchie",
                                    29.95));
            foreach(Book b in prog.list)
            {
                // Cannot modify an entire element in a foreach loop 
                // even with reference types.
                // Use a for or while loop instead
                if(b.Title == "The C Programming Language")
                    b = new Book("Programming Windows, 5th Ed.", "Petzold", 29.95); //CS1654
            }

            //With a for loop you can modify elements
            //for(int x = 0; x < prog.list.Count; x++)
            //{
            //    if(prog.list[x].Title== "The C Programming Language")
            //        prog.list[x] = new Book("Programming Windows, 5th Ed.", "Petzold", 29.95);
            //}
            //foreach(Book b in prog.list)
            //    Console.WriteLine(b.Title);

        }
    }
}

foreach ループ以外のコンテキストで CS1656 が生成される可能性がある例を次に示します。

// CS1656.cs
// compile with: /unsafe
using System;

class C : IDisposable
{
    public void Dispose() { }
}

class CMain
{
    unsafe public static void Main()
    {
        using (C c = new C())
        {
            c = new C(); // CS1656
        }

        int[] ary = new int[] { 1, 2, 3, 4 };
        fixed (int* p = ary)
        {
            p = null; // CS1656
        }
    }
}