人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

VB.NETやC#の構造体において、デフォルトコンストラクタを定義できない理由を教えてください。
引数付きのコンストラクタが定義できるのに、デフォルトコンストラクタが定義できないのが不思議です。

●質問者: witt
●カテゴリ:コンピュータ
✍キーワード:C# VB.NET コンストラクタ デフォルト 不思議
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● dasm
●27ポイント

C# の言語仕様ですが、

http://www.csharpfriends.com/Spec/index.aspx?specID=11.1.1.htm

Because every value type implicitly has a public parameterless instance constructor, it is not possible for a struct type to contain an explicit declaration of a parameterless constructor.

つまり、全ての構造体は既に (implicitly) 引数なしのコンストラクタ (default constructor) が定義されているので、(explicit に) 定義できない、とあります。

http://www.csharpfriends.com/Spec/index.aspx?specID=18.3.8.htm

Unlike a class, a struct is not permitted to declare a parameterless instance constructor. 2 Instead, every struct implicitly has a parameterless instance constructor, which always returns the value that results from setting all value type fields to their default value and all reference type fields to null.

その代わり、そのデフォルトコンストラクタは全ての値をデフォルト値にセットし、リファレンスは null にする、とあります。

更に深い話は言語設計に携わっている人でないと難しいと思いますが (Microsoft のサイトを見れば見つかるかもしれません)、求めている回答でなければポイントはお返しします。

◎質問者からの返答

ご回答いただいたC# の言語仕様については知っておりますので、更に深い話をお待ちしております。


2 ● dasm
●27ポイント

少しだけ深い話をしたいと思うのですが、

http://www.yoda.arachsys.com/csharp/faq/#struct.constructors

The .NET runtime can't guarantee that parameterless constructors will be called. If structs where to allow default, parameterless constructors, it would imply that these default constructors would *always* be called. However, the runtime can not make this guarantee. For example an array of value types will be initialized to the initial values of its members (i.e. 0 for number type primitive members, null for reference types etc) not to the values provided in a default constructor - which makes structs better performing by not having to call constructor code. Enforcing a minimum of one parameter in the constructor reduces the possibility that someone will define a constructor that they then expect to be called every time one of their struct types is constructed.

.NET Runtime では、デフォルトコンストラクタが呼ばれることを保証できません。もし許してしまえば常にデフォルトコンストラクタが呼ばれることになります。デフォルトコンストラクタを呼ばないことでパフォーマンスが上がります。引数を一つ以上に制限することで、コンストラクタの定義の手間を省くことができます、と言っています。

http://www.codeproject.com/csharp/structs_in_csharp.asp

Although the CLR allows it, C# does not allow structs to have a default parameterless constructor. The reason is that, for a value type, compilers by default neither generate a default constructor, nor do they generate a call to the default constructor. So, even if you happened to define a default constructor, it will not be called and that will only confuse you.

CLR ではデフォルトコンストラクタの定義を許しています。

C# の構造体では

struct MyStrstrcut

{

int i=10; //illegal

}

のようなフィールドの初期化が許されない為、必ず全てのフィールドを初期化する引数つきのコンストラクタを定義する必要がある。デフォルトコンストラクタを定義できるとユーザを混乱させてしまうから禁止しているんだ、と言っています。


ひょっとしたらもっと深い話を希望されているかもしれませんが、結局は言語設計者の方針として、コンストラクタの定義の手間を減らしたい、ユーザの混乱を減らしたい、パフォーマンスを上げたいということがあるからではないでしょうか。

◎質問者からの返答

ありがとうございます。このレベルの深い話を期待してました。

ただ、.NET Runtime は CLR とILのライブラリを併せたものと考えていたので、

>.NET Runtime では、デフォルトコンストラクタが呼ばれることを保証できません。

>CLR ではデフォルトコンストラクタの定義を許しています。

の記述が矛盾しているように感じ、混乱しています。


3 ● dasm
●26ポイント

私は C# に精通しているわけではないので、詳しい説明は他に出来る方がいればその方に譲りたいのですが、先の回答で「CLR ではデフォルトコンストラクタの定義を許しています」としたのは、「クラス型」であり、「構造体」は「クラス型」に含まれないのではないでしょうか? (CLR についてよく知らないのでただの推測です)

http://ja.wikipedia.org/wiki/C_Sharp

構造体は「値型オブジェクト」とあります。CLI では「クラス型 (Class Type)」と「値型 (Value Type)」があり、「値型」である「構造体」はデフォルトコンストラクタに関する制約を受けないのではないかと思います。

CLI については巨大な pdf が公開されています。

http://www.ecma-international.org/publications/files/ECMA-ST/Ecm...

参考:

http://ja.wikipedia.org/wiki/.NET_Framework

http://www.ecma-international.org/publications/standards/Ecma-33...

◎質問者からの返答

ありがとうございました。

「CLR では(構造体ではなく、クラス型の)デフォルトコンストラクタの定義を許しています」

という解釈で良さそうですね。もう少し調べてみたいと思います。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ