質問

次のスニペットを取得します。

List<int> distances = new List<int>();

冗長性は言語設計者が意図したものですか?もしそうなら、なぜですか?

役に立ちましたか?

解決

コードが冗長であると思われる理由は、初心者プログラマーにとって、同じことを2回定義しているように見えるためです。しかし、これはコードが行っていることではありません。これは、たまたま同じタイプである2つの別個のものを定義しています。以下を定義しています:

  1. List<int>タイプのdistancesという名前の変数。
  2. タイプ<=>のヒープ上のオブジェクト。

次のことを考慮してください:

Person[] coworkers = new Employee[20];

ここでは、変数と割り当てられたオブジェクトが2つの異なるタイプであるため、非冗長性がより明確になっています(object <!>#8217; sタイプがvariable <!>#から派生または実装している場合に有効な状況です8217; s type)。

他のヒント

これについて何が冗長ですか?

List<int> listOfInts = new List<int>():

英語に翻訳:(編集、説明のために少し整理)

  • List <!> lt; int <!> gt;型のポインターを作成します。 listofIntsという名前を付けます。
  • listOfIntsは作成されましたが、nowhere(null)を指す単なる参照ポインター
  • 次に、タイプList <!> lt; int <!> gt;のオブジェクトを作成します。ヒープ上で、listOfIntsへのポインタを返します。
  • 今listOfIntsはList <!> lt; int <!> gt;を指します。ヒープ上。

それが何をするかを考えると、あまり冗長ではありません。

もちろん代替手段があります:

var listOfInts = new List<int>();

ここでは、C#の型推論を使用しています。これは、C#にすぐに割り当てるため、C#は、ヒープに作成されたばかりのオブジェクトによって作成する型を判断できるためです。

CLRが型を処理する方法を完全に理解するには、 C#経由のCLR 。

常に言うことができます:

 var distances = new List<int>();

型を宣言することは、必ずしも初期化とは関係がないためです。

宣言できます

List<int> foo; 

その後、初期化するためにそのままにしておきます。冗長性はどこにありますか?たぶん、BuildList()のような別の関数から値を受け取ります。

他の人が言及したように、新しいvarキーワードを使用するとそれを回避できますが、コンパイラが変数のタイプを認識できるように、宣言時に変数を初期化する必要があります

それを冗長であると考えるのではなく、そのコンストラクトを行を保存できる機能と考えてください。

持つ代わりに

距離のリスト。 distances = new List();

c#では、それらを1行に配置できます。

1行に<!> quot;とある変数は distances と呼ばれ、List型の変数になります。<!> quot;別の行には、<!> quot;新しいリストを割り当てて、パラメータなしのコンストラクタ<!> quot;を呼び出します。

それは余りにも冗長ですか?おそらく。このようにすると、いくつかのことができますが、

1 。オブジェクト宣言から変数宣言を分離します。許可:

IEnumerable<int> distances = new List<int>();
// or more likely...
IEnumerable<int> distances = GetList();

2。コンパイラによるより強力な静的型チェックが可能になります-ランタイムエラーではなく、宣言が割り当てに一致しない場合にコンパイラエラーが発生します。

これらの両方は、ソフトウェアの作成に必要ですか?いいえ。これを行わない言語や、他の多くの点で異なる言語がたくさんあります。

<!> quot; Doctor!これをやると痛い!<!> quot; -<!> quot;もうやらない<!> quot;

c#が提供するものが必要ない、または必要ない場合は、他の言語を試してください。それらを使用しなくても、他のものを知っていると、問題へのアプローチ方法が大幅に向上します。使用する場合は、素晴らしい!

いずれにせよ、あなたは<!> quot;と言うのに十分な視点を見つけるかもしれません; c#コンパイラーによって実施される厳密な静的型チェックは必要ありません。私はpython <!> quot;を使用しますが、C#を過度に冗長にするのではなく、

することもできます:

var distances = new List<int>();

C#3.0(.Net 3.5に対応)のコンパイラーの改善により、この種の問題のいくつかが解消されました。したがって、コードは次のように記述できます。

var distances = new List<int>();

更新されたコンパイラーは、ステートメント内の追加情報に基づいて型を判別するのがはるかに優れています。つまり、割り当てのために、またはジェネリックの一部としてタイプを指定する必要があるインスタンスが少なくなります。

それは言われていることですが、改善できる分野がまだいくつかあります。その一部はAPIであり、一部は単純に厳密な型指定の制限によるものです。

冗長性自体は意図されていませんでしたが、すべての変数とフィールドが型宣言を持つ必要があるという事実の副作用でした。すべてのオブジェクトのインスタンス化が new 式で型の名前も言及していることを考慮すると、冗長なステートメントが得られます。

var キーワードを使用した型推論により、その冗長性を排除できます。コンパイラーはそれを理解するのに十分なほど賢いです。次のC ++には、同じことを行う auto キーワードもあります。

彼らが var を導入した主な理由は、名前のない匿名型でした:

var x = new {Foo = Bar, Number = 1};

<!> quot;冗長な<!> quot;動的に型付けされた言語と比較する場合。コンパイル時に多態性やバグを見つけるのに役立ちます。また、IDEでコードの自動補完/インテリセンスが簡単になります(使用する場合)。

静的型付けの歴史的な成果物/ C構文。 Rubyの例を比較します:

distances = []

C#は、機能サポートの追加後、明らかに冗長性が低下しています。

読者にタイプが明らかな場合は、varを使用します。

//Use var here
var names = new List<string>();

//but not here
List<string> names = GetNames();

microsofts C#プログラミングガイド

から
  

varキーワードも役立ちます   特定のタイプの変数   キーボードで入力するのが面倒、または   明らかである、または追加しない   コードの読みやすさ

あなたの特定の例は確かに少し冗長ですが、ほとんどの場合、C#はやや無駄がありません。

私はこれを好む(C#)

int i;

これへ(VB.NET)

Dim i as Integer

今、あなたが選んだ特定の例は、一般的に.NETについてのものであり、少し長めですが、それはC#のせいではないと思います。たぶん質問を言い換える必要があります<!> quot; .NETコードがなぜそんなに冗長なのですか?<!> quot;

そのような怠のためにvarを使用することに関するもう1つの問題があります

var names = new List<string>();

varを使用する場合、<!> quot; names <!> quotという名前の変数。 List<string>,と入力されますが、最終的にはList<T>.

によって継承されたインターフェイスの1つのみを使用します
IList<string> = new List<string>();
ICollection<string> = new List<string>();
IEnumerable<string> = new List<string>();

そのすべてを自動的に使用できますが、コードの作成時に使用したいインターフェイスを検討できますか?

この例では、varキーワードは読みやすさを向上させません。

この質問に対する多くの回答では、著者はコンパイラーや謝罪者のように考えています。優れたプログラミングの重要なルールは、繰り返さないことです

この不要な繰り返しを避けることは、Goの明示的な設計目標です。たとえば、

  

St音( foo.Foo * myFoo = new(foo.Foo))は、:= declare-and-initializeコンストラクトを使用した単純な型の派生によって削減されます。

私たちはコンパイラとコンパイラエラーにはまっているからです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top