c嗳重ね着と列挙器を深く理解する。
皆さん、こんにちは、これは「C铉.NET拾遺漏補完」シリーズの07編の文章です。
C〓〓の中で、大多数の方法はすべてreturn文を通じて(通って)直ちにプログラムのコントロールを调节者に手渡すので、同时に方法の内の当地の资源をも放してしまうことができます。一方、yield文を含む方法は、順番に複数の値を返して調整者に与えた期間にローカルリソースを保持し、すべての値が戻ってきたら元のリソースを解放し、これらの戻り値は一連のシーケンスを形成して使用者によって使用される。C〓の中で、このようなyieldの語句を含む方法、属性あるいは索引はシーズマリーです。
ディケンサのyield文は2つに分けられます。 yeild returnは、プログラム制御権をコーディネーターに戻してローカルの状態を保持し、コーディネーターが戻ってきた値を取って後で実行します。 yeild breakは、プログラムの現在のシーケンスが終了していることを知らせるために、通常のコードブロックに相当するreturn文(ディケンサで直接にreturnを使用するのは違法です)。
1
1
2
3
5
8
13
21
34
55
実際のシーンでは、私たちは普通、直接的にはあまり書きません。反復が必要なシーンの多くは配列、セット、リストです。これらのタイプの内部はすでに必要なローズマリーをカプセル化しました。例えばC〓〓の配列がトラバースされるのは、IEnumerableインターフェースが実現されたためであり、Get Enumerator()法により配列の列挙器Enumeratorが得られます。たとえば、最も一般的な使用シーンは、次のように配列要素を1つずつ印刷する配列の例である。 オブジェクトに元素が含まれていますか?よく見られます。
また、例えばEF Coreでは、実行が必要です。
以上はcylaのディテールと列挙器の詳細を深く理解しています。cylaのディテールと列挙器に関する資料は他の関連記事に注目してください。
C〓〓の中で、大多数の方法はすべてreturn文を通じて(通って)直ちにプログラムのコントロールを调节者に手渡すので、同时に方法の内の当地の资源をも放してしまうことができます。一方、yield文を含む方法は、順番に複数の値を返して調整者に与えた期間にローカルリソースを保持し、すべての値が戻ってきたら元のリソースを解放し、これらの戻り値は一連のシーケンスを形成して使用者によって使用される。C〓の中で、このようなyieldの語句を含む方法、属性あるいは索引はシーズマリーです。
ディケンサのyield文は2つに分けられます。
IEnumerable<int> Fibonacci(int count)
{
int prev = 1;
int curr = 1;
for (int i = 0; i < count; i++)
{
yield return prev;
int temp = prev + curr;
prev = curr;
curr = temp;
}
}
void Main()
{
foreach (int term in Fibonacci(10))
{
Console.WriteLine(term);
}
}
出力:1
1
2
3
5
8
13
21
34
55
実際のシーンでは、私たちは普通、直接的にはあまり書きません。反復が必要なシーンの多くは配列、セット、リストです。これらのタイプの内部はすでに必要なローズマリーをカプセル化しました。例えばC〓〓の配列がトラバースされるのは、IEnumerableインターフェースが実現されたためであり、Get Enumerator()法により配列の列挙器Enumeratorが得られます。たとえば、最も一般的な使用シーンは、次のように配列要素を1つずつ印刷する配列の例である。
int[] numbers = { 1, 2, 3, 4, 5 };
IEnumerator enumerator = numbers.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
実はこれがforeachの作業原理です。上のコードはforeachで次のように書き換えられます。
int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
Console.WriteLine(number);
}
もちろん、列挙器は必ずしもローズマリーによって実現されなくてもいいです。例えば、以下のカスタムの列挙器Coffee Enumeratorです。
public class CoffeeCollection : IEnumerable
{
private CoffeeEnumerator enumerator;
public CoffeeCollection()
{
enumerator = new CoffeeEnumerator();
}
public IEnumerator GetEnumerator()
{
return enumerator;
}
public class CoffeeEnumerator : IEnumerator
{
string[] items = new string[3] { "espresso", "macchiato", "latte" };
int currentIndex = -1;
public object Current
{
get
{
return items[currentIndex];
}
}
public bool MoveNext()
{
currentIndex++;
if (currentIndex < items.Length)
{
return true;
}
return false;
}
public void Reset()
{
currentIndex = 0;
}
}
}
使用:
public static void Main(string[] args)
{
foreach (var coffee in new CoffeeCollection())
{
Console.WriteLine(coffee);
}
}
ディケンサと列挙器を理解することで、より効率的なコードを作成することができます。例えば一つを判断する IEnumerable
if(enumerable.Count() > 0)
{
//
}
ただし、列挙器の思考で少し考えれば分かります。Count() 集合要素の数を得るためには、必ずすべての要素が反復され、時間の複雑さはO(n)である。セットに要素が含まれているかどうかを知るだけで、実は反復すればいいです。だから効率のいいやり方は:
if(enumerable.GetEnumerator().MoveNext())
{
//
}
このように書く時間の複雑さはO(1)で,効率は明らかにより高い。書くのが便利なために、C〓は拡張方法を提供しました。 アンy()
if(enumerable.Any())
{
//
}
必要があれば、できるだけAny方法を使って、効率がいいです。また、例えばEF Coreでは、実行が必要です。
IQueryable<T>
お問い合わせの際に、時々使うことがあります。 AsEnumerable()
ToList、ToArayなどを使うより効率的です。ToList、ToArayなどはすぐに列挙操作を行います。 As Enumerable() 列挙操作を本当に必要な時に延期して実行してもいいです。もちろん、実際の応用シーンも考慮して、Aray、Listなどは調整者に使いやすく、特に元素の総数量、添削要素などの操作を取得します。以上はcylaのディテールと列挙器の詳細を深く理解しています。cylaのディテールと列挙器に関する資料は他の関連記事に注目してください。