C#では、foreachループの中で値型インスタンスのメンバを変更できないのはなぜですか?
2023-08-20 04:15:52
質問
値型は不変であるべきだということは知っていますが、それは単なる提案であって、規則ではありませんよね? では、なぜこのようなことができないのでしょうか。
struct MyStruct
{
public string Name { get; set; }
}
public class Program
{
static void Main(string[] args)
{
MyStruct[] array = new MyStruct[] { new MyStruct { Name = "1" }, new MyStruct { Name = "2" } };
foreach (var item in array)
{
item.Name = "3";
}
//for (int i = 0; i < array.Length; i++)
//{
// array[i].Name = "3";
//}
Console.ReadLine();
}
}
コード内のforeachループはコンパイルできませんが、コメントされたforループは問題なく動作します。エラーメッセージです。
item'は'foreach iteration variable'であるため、メンバを変更できません。
なぜでしょうか?
どのように解決するのですか?
foreach は列挙子を使用しており、列挙子は基になるコレクションを変更することはできないためですが はできます。 しかし、任意のオブジェクト によって参照される によって参照されるオブジェクトを変更します。ここで、ValueとReferenceタイプのセマンティクスが登場する。
参照型、つまりクラスでは、コレクションが保存しているのはオブジェクトへの参照だけです。そのため、コレクションはオブジェクトのどのメンバーにも実際に触れることはなく、それらについてあまり気にすることはありません。オブジェクトを変更しても、コレクションは変更されません。
一方、値型はコレクションにその構造全体を保存します。コレクションを変更し、列挙者を無効にすることなく、そのメンバーに触れることはできません。
さらに、列挙者が返す コピー を返します。ref型では、これは何の意味もありません。参照のコピーは同じ参照になり、参照されたオブジェクトを好きなように変更でき、その変更はスコープの外に広がります。一方、value-typeでは、オブジェクトのコピーしか得られないため、そのコピーに対する変更は決して伝搬しません。
関連
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み] PHP foreach ループ キー値
-
[解決済み] foreachループの現在の反復処理のインデックスを取得するにはどうすればよいですか?
-
[解決済み] 汎用クラスやメソッドのメンバからTの型を取得する方法
-
[解決済み] foreachループの最初と最後の繰り返しを決定する方法は?
-
[解決済み] C#では、なぜStringは値型のように動作する参照型なのですか?
-
[解決済み】Foreachループ、ループの最後の反復がどれかを判断する
-
[解決済み] foreachループで配列の値を変更する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】スクリプトクラスが見つからないので、スクリプトコンポーネントを追加できない?
-
[解決済み] エンティティタイプ <type> は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み】Visual studio 2019がデバッグ時にフリーズする件
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み] 2つのリストを結合する
-
[解決済み】URLから画像をダウンロードする方法