C#で構造体を操作する方法

クラスと構造体の間には多くの類似点がありますが、いくつかの明確な違いもあります。最も重要なことは、クラスとは異なり、構造体は値型です。したがって、クラスのインスタンスはヒープに格納されますが、構造体のインスタンスはスタックに格納されます。

構造体のインスタンスがメソッドに渡されるとき、それは常に値によって渡されます。これは、クラスのインスタンスをメソッドに渡すときに発生することとは対照的です。インスタンスは参照によって渡されます。

C#でのプログラミング構造体

構造体を宣言するための構文は次のようになります。

struct

{

//Data members and member functions of the struct

}

The following code snippet shows how a typical struct definition looks like.

struct Rectangle

    {

        public int width;

        public int height;

    }

これで、以下のコードスニペットに示すように、前に定義した構造体のメンバーに値を割り当てることができます。

Rectangle rectangle = new Rectangle();

rectangle.width = 10;

rectangle.height = 15;

上記のコードスニペットは、Rectangle構造体のインスタンスを作成し、そのパブリックメンバーに値を割り当てます。構造体内にメンバーデータとメソッドの両方を含めることができることに注意してください。また、メンバーをプライベート、パブリック、および内部として指定できます。クラスとは異なり、構造体に非静的フィールドのフィールド初期化子を含めることはできないことに注意してください。したがって、構造体の次のようなステートメントは無効です。

int width = 10;

int height = 15;

とにかく、構造体の静的メンバーを初期化できます。したがって、以下は構造体内の有効なステートメントです。

static int area = 0;

次に、構造体にいくつかのメソッドを追加しましょう。これは、以前に作成したRectangle構造体の更新バージョンです。パラメータ化されたコンストラクタの使用法に注意してください。

struct Rectangle

    {

        int width;

        int height;

        public Rectangle(int width, int height)

        {

            this.width = width;

            this.height = height;

        }

        public int GetArea()

        {

            return this.width * this.height;

        }

    }

構造体内で明示的なパラメーターなしのコンストラクターを定義できない場合でも、構造体内にパラメーターコンストラクターをいつでも含めることができることに注意してください。また、クラスと同様に、構造体にコンストラクターをオーバーロードすることもできます。Rectangle構造体のコンストラクターを使用して値を設定し、GetArea()メソッドを呼び出して領域を取得する方法は次のとおりです。クラスと同様に、構造体内に静的メソッドと非静的メソッドを含めることができることに注意してください。

static void Main(string[] args)

        {

            Rectangle rectangle = new Rectangle(10, 15);

            int area = rectangle.GetArea();

            Console.WriteLine("The area is: " + area.ToString());

            Console.Read();

        }

クラスと同様に、構造体はプロパティとインデクサーのサポートを提供します。構造体とクラスの大きな違いの1つは、クラスとは異なり、構造体は継承をサポートしていないことです。別のクラスまたは構造体を拡張する構造体を持つことはできません。ただし、クラスと同様に、構造体はインターフェイスを実装できます。これを説明するコード例を次に示します。

 interface IRectangle

    {

        int GetArea();

    }

  struct Rectangle : IRectangle

    {

        int width;

        int height;

        public Rectangle(int width, int height)

        {

            this.width = width;

            this.height = height;

        }

        public int GetArea()

        {

            return this.width * this.height;

        }

    }

クラスと構造体のどちらを選択するか

今、私たちは興味深い議論のポイントに来ています。クラスに対して構造体を使用する必要があるのはいつですか。その逆も同様です。

この記事の前半で説明したように、構造体のインスタンスはスタックに作成され、クラスのインスタンスはマネージヒープに作成されます。値型の割り当てと割り当て解除は、参照型よりも安価です。構造体は、いくつかのデータメンバーを保持する複合データ型を作成する必要がある場合に適しています。理想的には、構造体のデータメンバーのサイズは16バイト未満である必要があります。値のセマンティクスを持ち、少数のデータメンバーのみを含む小さな複合データ構造を構築する場合は、構造体を選択できます。このような場合にstructを使用すると、ガベージコレクションに関連するオーバーヘッドを回避できます。

構造体を操作するときは、推奨されるベストプラクティスに従う必要があります。この記事で推奨されているサイズよりも大きいサイズの構造体の使用は避けてください。また、構造体のインスタンスをメソッドに渡すことは、クラスのインスタンスを渡すよりもパフォーマンスの点でコストがかかることに注意してください。小さなデータ構造で作業する場合は、構造体を使用することをお勧めします。このトピックの詳細については、このMSDNの記事を参照してください。