2017-02-16 18 views
3

this codeの例をC# 7.0で見ていましたが、このループの下で何が起こっているのか、このループのパフォーマンスについてはわかりませんでした。C#7を使用したforeach宣言でのヌル統合オペレータ

foreach (var c in text ?? throw new ArgumentNullException(nameof(text))) 
{ 
    ... 
} 

私の質問:

  1. は、条件文を一度押すか( 各反復で)複数回取得していますか?
  2. 新しい構文は異なって見えますが、このようにするとどのような利点がありますか?
+5

テスト時にパフォーマンスにどのような影響がありましたか?あなたはそれを試したのですか?あなた自身であなたの質問に対する答えを理解するためのテストでは不十分であった理由を説明してください。あなたがテストしたことをはっきりと示している良い[mcve]が含まれるように質問を修正し、あなたのテストについて正確に理解できないことについての詳細な説明を含めてください。 –

+2

1回。 'text'がヌルの場合、条件文は一度ヒットします。これは説明なしで論理的でなければなりません。ループしている場合は、列挙子がループされているために1回だけ表示されます。 –

+0

@PeterDuniho質問の枠組みが間違っているか分かりません。 – Svek

答えて

2

if (text == null) // or string.IsNullOrEmpty for strings 
    throw new ArgumentNullException(nameof(text)); 

foreach (var c in text) 
{ 
    // ... 
} 


私は、広く使われている一般的な良い習慣を使用することをお勧めしますこのC#の機能を理解するには、内部コードforeachを理解する必要があります。 foreach文の式の右側部分はIEnumerable(<T>)インタフェースを実装する必要があり、全体のループは、内部的に、このような単純なwhile、何かである:

// here can be NullReferenceException 
var en = text.GetEnumerator(); 
while(en.MoveNext()) 
{ 
    var c = en.Current; 
    { 
     ... 
    } 
} 

あなたが見ることができるように、このコード内のポイントがありますNREすることができます

if (text.IsNullOrWhitespace()) 
{ 
    throw new ArgumentNullException(nameof(text)); 
} 

// while loop here or text.SomeLinqCodeHere() 

が本当に不要ではありません、ここでのコードのいくつかの行があり、いくつかのエントロピーを追加し、:あなたはこのような列挙前にループ全体またはEnumerable extensions classを、チェックする必要があるので、発生本当の価値はありません。 foreachシンプルなそれは本当に意見ベースのコードの規格についての決定が、この機能の真の目的の場合には、このように、?. operatorのように、C#7に他の新しいもので、それを連鎖さ:投げるような場合には

int? length = customers?.Length ?? throw new ...; 
Customer first = customers?[0] ?? throw new ...; 
int? count = customers?[0]?.Orders?.Count() ?? throw new ...; 

int? length = customers?.Length; // should not be null 
Customer first = customers?[0]; // should not be null 
int? count = customers?[0]?.Orders?.Count(); // should not be null 

が、それはあなたのコードのためのいくつかの厳格な契約のようなルールを追加します。例外は、コードの行の末尾にコメントすることは似ています。このような式でforeachループのパフォーマンスについては

、すでに言ったように、それは列挙子を取得することは、一度だけ発生するよう苦しみ、そして 前の実ループしません。

9

"foreachの動作方法"に関して、条件文は一度だけ計算されます。

あなたはこれらの質問にどのように機能するかのforeachループの詳細を読むことをお勧めします


How do foreach loops work in C#?
Does foreach evaluate the array at every iteration?

感謝をSvekには、Visual Studioの後にリリースされる新しいC#7.0の機能であることを説明するために2017 RC:
http://structuredsight.com/2016/09/01/c-7-additions-throw-expressions/

私は「利点は何か」は、意見に基づいた質問の一種だと思います。
私の意見では、それは良いことは何ももたらさず、用語やコードの読みやすさにはちょっと醜いです。おそらく、我々は数年で、nullで合体+スロー例外の使用状況が表示され、それが新しい標準になるだろう:)

+3

それはそれほど良くないかもしれません。元のコードはスレッドセーフでもスレッドセーフでなくてもかまいませんが、あなたのバージョンはそうではありません。なぜこれが良かったと言ったのか説明できますか? – Enigmativity

+3

前の段落によると、私は "コードの可読性とフロー"という点でより良いと言いました。値が最初にnullであるかどうかをチェックするか、またはメソッドと 'ArgumentNullException'を投げることは、よくある一般的な方法です**。これは、すべての.NETクラス、サードパーティクラス、およびすべての優れた開発者が行うこととまったく同じです。誰もが望むようにコード演算子と機能を使い始めると、すぐにお互いのコードを理解しなくなります。ショートコード!=より良い。 –

+0

スレッドの安全性について言えば、私は 'text'が関数に渡される引数であると仮定しました。もし私が正しければ、このコードは常に**スレッドセーフです。異なる場合に変更可能なクラスメンバであれば、スレッドセーフを提供できる他の多くの手法、アプローチ、機能があります。新しいExceptionを投げるためにヌル合体演算子を使用することは、間違いなくその1つではありません。 –

関連する問題