const
とreadonly
似ていますが、まったく同じではありません。
const
フィールドには、その値は、コンパイル時に計算できることを意味し、コンパイル時定数です。あreadonly
フィールドには、いくつかのコードは、タイプの建設中に実行されなければならない追加のシナリオが可能になります。作成後、readonly
フィールドは変更できません。
たとえば、const
メンバーは次のようなメンバーの定義に使用できます。
struct Test
{
public const double Pi = 3.14;
public const int Zero = 0;
}
3.14や0などの値はコンパイル時の定数なので。ただし、タイプを定義し、そのプレハブインスタンスをいくつか提供する場合を考えてみます。たとえば、Colorクラスを定義して、Black、Whiteなどの一般的な色に「定数」を提供する場合があります。constメンバーを使用してこれを行うことはできません。右側がコンパイル時の定数ではないためです。通常の静的メンバーでこれを行うことができます:
public class Color
{
public static Color Black = new Color(0, 0, 0);
public static Color White = new Color(255, 255, 255);
public static Color Red = new Color(255, 0, 0);
public static Color Green = new Color(0, 255, 0);
public static Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
しかし、その場合は、おそらく黒と白の値を交換することによって、Colorのクライアントがそれをいじるのを防ぐ方法はありません。言うまでもなく、これはColorクラスの他のクライアントを驚かせます。「読み取り専用」機能は、このシナリオに対処します。
readonly
宣言にキーワードを単純に導入することで、クライアントコードが不正に動作するのを防ぎながら、柔軟な初期化を維持します。
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
constメンバーは常に静的ですが、読み取り専用メンバーは通常のフィールドと同様に静的でもそうでなくてもかまいません。
これら2つの目的で単一のキーワードを使用することは可能ですが、これによりバージョン管理の問題またはパフォーマンスの問題が発生します。この(const)に単一のキーワードを使用して、開発者が書いたと仮定します。
public class A
{
public static const C = 0;
}
別の開発者がAに依存するコードを記述しました。
public class B
{
static void Main() => Console.WriteLine(A.C);
}
さて、生成されたコードは、ACがコンパイル時の定数であるという事実に依存できますか?つまり、ACの使用を値0に置き換えることができますか?これに「はい」と答えると、それはAの開発者がACの初期化方法を変更できないことを意味します。これは、許可なくAの開発者の手を結びます。
この質問に「いいえ」と答えると、重要な最適化が行われなくなります。おそらく、Aの作者は、ACが常にゼロであることを肯定しています。constとreadonlyの両方を使用すると、Aの開発者が意図を指定できます。これにより、バージョン管理の動作とパフォーマンスが向上します。
static readonly
:内部でのconstを使用してみてくださいIEnumerator
引き金と思われるunrecheableをyield
、あなたは恐ろしい「内部コンパイラエラー」を取得します。Unity3D外でコードをテストしませんでしたが、これはモノまたは.NET バグのいずれかであると確信しています。それは、C#のそれにもかかわらず問題。