program study story

プログラムの勉強 アウトプット

C# クラスと構造体についてメモ

構造体とは

ある対象に関連する項目をまとめて1つのかたまりにしたもの

関連する項目はフィールド(メンバ変数)と呼ばれ、変数や文字列などをフィールドとする
ことができます。
フィールドを使い、処理を定義することが可能。

同じように項目をまとめて1つのかたまりにしたもので、配列があります。
配列の場合、同じ型のモノしか1つのかたまりにできません。

構造体はint型や文字列など型の違うモノでも1つのかたまりにできます。

構造体とクラスについて

共通点:
インスタンス化して使用(インスタンス化して使用)
・メソッドの定義(フィールドだけでなく、メソッドを定義して処理を行うことが出来る)
・引数ありコンストラクタの定義(インスタンス化してフィールドの値を初期化する場合などに使用)
・インターフェースを実装(複数実装も可)

違い:
インスタンス化したオブジェクトの型。
                    構造体   クラス
オブジェクトの型             値型    参照型
クラスの継承              ※不可    可能
フィールド初期化子の使用         不可    可能 
デフォルトコンストラクタ(引数の定義)   不可    可能
デストラクタの定義            不可    可能

※System.ValuTypeのみ継承継承元にはなれない

使い分け:
構造体は、制限がクラスに比べて多い分、軽量のオブジェクトを表すのに適している。
参照型の機能が必要ない場合は、
クラスとして実装するよりは構造体として定義した方が効率的に処理される

例えば、3次元の点座標を大量に扱うCGなどで使用する場合など。。。

 

 

★基本的な定義
[修飾子] struct 構造体名
{
 フィールド(メンバ変数)
}
例え:
public struct Grid
{
public int x;
public int y;
public int z;
}

★コンストラクタの定義
構造体では、引数ありのコンストラクタを定義することができます。
例え:
public struct Grid
{
public int x;
public int y;
public int z;

public Grid(int x,int y,int z){
this.x = x;
this.y = y;
this.z = z;
}
}
★メソッドの定義
構造体でメソッドを定義することも可能
public struct Circle
{
public double r;

public Circle (double rad){
r = rad;
}

public double CalcCircum(double r){
return 3.14 * 2 * r;
}

public double CalcArea(double r){
return 3.14 * r * r;
}
}

★構造体を定義する際の注意
・構造体のフィールドは初期化子を使用することはできない。
・引数なしのコンストラクタを定義することもできない。
public struct Grid
{
public int x;
public int y;
public int z;

/* 初期化子の使用はコンパイルエラー
public int x = 0;
public int y = 0;
public int z = 0;
*/

public Grid(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}

/* 引数なしのコンストラクタの定義はコンパイルエラー
public Grid() {
this.x = 0;
this.y = 0;
this.z = 0;
}
*/
}
★構造体の初期化
構造体をインスタンス化して初期化する方法はいくつかある。
クラスと同様にnew演算子を使う方法など。
using System;

namespace Sample
{
public struct Circle
{
public double r;

public double CalcCircum(double r) {
return 3.14 * 2 * r;
}

public double CalcArea(double r) {
return 3.14 * r * r;
}
}

class Sample
{
static void Main()
{
・方法1.new演算子を使う方法
Circle c1 = new Circle();
c1.r = 10.0;
Console.WriteLine("半径{0}の円周は{1}、面積は{2}", c1.r, c1.CalcCircum(c1.r), c1.CalcArea(c1.r));

・方法2.new演算子を使わない方法
Circle c2;
c2.r = 20.0;
Console.WriteLine("半径{0}の円周は{1}、面積は{2}", c2.r, c2.CalcCircum(c2.r), c2.CalcArea(c2.r));

・方法3.インスタンス化と同時に初期化
Circle c3 = new Circle() {r = 30.0};
Console.WriteLine("半径{0}の円周は{1}、面積は{2}", c3.r, c3.CalcCircum(c3.r), c3.CalcArea(c3.r));

Console.ReadKey();
}
}
}

★構造体のフィールドに配列を用いる
構造体のフィールドには、int型やdouble型、string型を指定できる。また、
配列を指定することもできる
using System;

namespace Sample
{
public struct Country
{
public string capital;
public string cities;
}

class Sample
{
static void Main()
{
Country japan = new Country() {
capital = "Tokyo",
cities = new string
{"Osaka", "Nagoya"}
};
Console.WriteLine(
"日本の首都は{0}、代表的な都市は{1}",
japan.capital, string.Join(", ", japan.cities)
);

Country usa = new Country() {
capital = "Washington, D.C.",
cities = new string{"NY", "LA"}
};
Console.WriteLine(
"アメリカの首都は{0}、代表的な都市は{1}",
usa.capital, string.Join(", ", usa.cities)
);

Console.ReadKey();
}
}
}

★構造体を要素とする配列
・配列の要素に構造体を指定することも可能。
using System;

namespace Sample
{
public struct Grid
{
public double x;
public double y;
}

class Sample
{
static void Main()
{
Grid grids = new Grid[5];

for(int i = 0; i < 5; i++) {
grids[i] = new Grid() {x = i * 1.0, y = 2 * i * 1.0};
}

foreach(var grid in grids) {
Console.WriteLine("x = {0}, y = {1}", grid.x, grid.y);
}

Console.ReadKey();
}
}
}