重複の可能性:
メソッドの外部でvarを使用する
class A {
string X;
}
// Proper
class A {
var X;
}
// Improper (gives error)
なぜ、クラスでvar型変数を宣言することができないのですか、それを達成するために何ができるのか、または代替手段は何ですか?
関数/メソッドでは、var型変数を宣言できますが、なぜできないのですか、クラスで宣言しますか?
ありがとう。
重複の可能性:
メソッドの外部でvarを使用する
class A {
string X;
}
// Proper
class A {
var X;
}
// Improper (gives error)
なぜ、クラスでvar型変数を宣言することができないのですか、それを達成するために何ができるのか、または代替手段は何ですか?
関数/メソッドでは、var型変数を宣言できますが、なぜできないのですか、クラスで宣言しますか?
ありがとう。
// method variable
var X;
メソッド内であっても、決して有効ではありません。タイプを推測するには、すぐに初期化する必要があります。
// method variable
var X = "abc"; // now a string
フィールド初期化子を使用するフィールドでこれが使用できない理由については、単純に、仕様にはそのように記載されています。仕様がそう言う理由は別の議論です...注釈付きの仕様を確認することはできますが、ロジックがより複雑なメソッド変数(LINQなど)では、それらがより必要であると単純に疑われます。また、それらはしばしば匿名型で使用されます(それはそれらの存在の必要性です)。ただし、匿名タイプはパブリックAPIで公開できないため、非常に混乱する可能性があります。
private var foo = new { x = 123, y = "abc"}; // valid
public var bar = new { x = 123, y = "abc"}; // invalid
全体として、私は現在のロジックに満足しています。
インスタンス変数が保持するオブジェクトのタイプが本当にわからない場合はobject
、ではなく、を使用してくださいvar
。var
「わからない」という意味ではなく、「自分のタイプを推測する」という意味です。これが、クラスのメンバーには使用できない理由です。
C#はこのレベルの型推論をサポートしていないためです。別の方法は、このレベルの型推論をサポートするF#などの言語を使用するか、C#チームに機能の実装を依頼することです。私はあなたがより幸運になるだろうかなり良い推測を持っています...
C#のvarは、指定された式のRHSから型を推測するために使用される暗黙的に型指定されたローカル変数であり、コンパイル時に解決する必要があります。クラス定義でRHS値のないvarを宣言する場合、コンパイラがvarに割り当てようとしている型を知る方法はありません。
C#は、クラス変数の暗黙的な型指定をサポートしていません。
varの実際のタイプは、それが使用されるコンテキストから推測されるためです。フィールド(クラスメンバー変数)の場合、そのようなコンテキストはありません。
var _users = new List<User>()
フィールド宣言として記述した場合、その意図は非常に明白であると主張できます。
問題は、すべてのフィールド宣言に、型を推測するために必要な割り当てが含まれているわけではないことです。(コンストラクターを使用してフィールドを初期化することをお勧めします)
通常の型宣言と通常の型宣言の両方を混在var
させると、厄介なスープのように見えます。したがって、それは不可能です。
(少なくともそれは私の推測です)
はい、var
キーワードはローカル変数にのみ許可されています。
これは、ローカルスコープにのみ存在する匿名型を処理できるようにするために言語で導入されました。var
匿名タイプはローカルスコープに制限されているため、ローカルスコープでのみキーワードを許可することは理にかなっています。
さらに、var
データ型を推測するために使用されるため、値を指定せずにキーワードを使用することはできません。
var x = "asdf"; // works
var x; // doesn't work
変数を宣言する通常の方法は、特定のデータ型を使用することです。var
データ型を指定できない場合(たとえば、型が匿名の場合)、または型が不要な場合(たとえば、値で文字通り繰り返される場合)にキーワードを使用します。例:
var x = new { Key = 42, Name = "asdf" };
var y = new System.Text.StringBuilder();
それはすべてビルド順序によるものです。varはメソッドでのみ宣言できます。コンパイラは最初にメソッド以外のすべてをビルドします。そのため、メソッド内でオブジェクトを使用すると、オブジェクトのタイプがコンパイラに明確になります。ジョンはこれについて素晴らしい答えを持っていましたが、見つけることができないようです。