readonlyキーワードを理解しよう!

[C#] readonlyキーワードを理解しよう!

※ 当サイトは広告を含みます。

ここではreadonlyキーワードを学びます。

readonlyキーワード

readonlyとは、read + onlyで読み取り専用を意味します。
例えばフィールドに書くことができ、そうすると読み取り専用のフィールドになります。


namespace Sample
{
  public class Test
  {
    public readonly int MaxValue = 1000;
  }

  internal class Program
  {
    static void Main(string[] args)
    {
      var obj = new Test();

      // 読み取り専用に代入するとビルドエラー
      //obj.MaxValue = 10;

      Console.WriteLine(obj.MaxValue);
    }
  }
}

部分的に抜き出すとここです。


public readonly int MaxValue = 1000;

正直、他にもいくつか記述可能な場所があるのですが、ほぼフィールドに記述するパターンしか使いません。
他にはreadonly structとかref readonly等があります。まぁ、興味ある人は公式を読んでください。
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/readonly

でっ、このreadonlyですが、読み取り専用なので初期化のタイミングが制限されます。
先程のようにフィールド宣言時に同時に初期化するか、コンストラクタ内でのみ初期化が可能です。


namespace Sample
{
  public class Test
  {
    public readonly int MaxValue;

    public Test()
    {
      // コンストラクタ内でのみ初期化が可能
      this.MaxValue = 1000;
    }
  }

  internal class Program
  {
    static void Main(string[] args)
    {
      var obj = new Test();

      // 読み取り専用に代入するとビルドエラー
      //obj.MaxValue = 10;

      Console.WriteLine(obj.MaxValue);
    }
  }
}

定数(constants)との違い

似た単語にconstがありますがconstは定数です。この定数とはコンパイル時点で確定してる必要があります。
つまり、0とか1みたいな数値、または文字列nullしかconstを指定することはできません。

対してreadonlyは初期化した値の読み取り専用を意味するため、どんな値でもreadonly化できます。
例えばクラス型にreadonlyを付けると、インスタンス生成後に書き換えできないインスタンスを作れます。


namespace Sample
{
  public class Test
  {
    public readonly Position Pos;

    public Test()
    {
      this.Pos = new Position()
      {
        X = 32,
        Y = 64,
      };
    }
  }

  public class Position
  {
    public int X { get; set; }
    public int Y { get; set; }
  }

  internal class Program
  {
    static void Main(string[] args)
    {
      var obj = new Test();

      // 読み取り専用なのでビルドエラー
      //obj.Pos = new Position();

      Console.WriteLine($"X={obj.Pos.X}, Y={obj.Pos.Y}");
    }
  }
}

注意というか、C#では常識の話ですが、これはクラスのインスタンスがreadonlyなので、読み取り専用なのは参照値です。
つまり、参照値が示す先のクラスが所有するオブジェクトは書き換えが可能です。ここに疑問を感じる人は以下を読んでください。

staticと併用する方法

const化できないフィールドをconstのように利用したい場合はstaticを併用します。
と言うのも、constはクラスに所属するため扱い的にはstaticの上位板です。

なので、readonlyのみではインスタンスに所属する読み取り専用のフィールドにしかなりません。
その値がインスタンスごとに異なる必要がないなら、staticを付けてクラスに所属させた方が良いです。


namespace Sample
{
  public class Test
  {
    public static readonly Position Pos = new Position()
    {
      X = 32,
      Y = 64,
    };
  }

  public class Position
  {
    public int X { get; set; }
    public int Y { get; set; }
  }

  internal class Program
  {
    static void Main(string[] args)
    {
      // クラスに属するので、アクセスはこうなる。
      Console.WriteLine($"X={Test.Pos.X}, Y={Test.Pos.Y}");
    }
  }
}
管理人
管理人

定数っぽく使いたいけどconstが無理ってパターンは凄く多い。そんな時にreadonlyを使おう。

あとがき

readonlyなんて、このパターンだけ覚えておけば十分。

◆ C#に関する学習コンテンツ

この記事は参考になりましたか?

関連記事

コメント

この記事へのコメントはありません。