2017-02-08 7 views
-2

エンティティがあり、その上にInvoiceLineを置くことができます。メインのInvoiceLineだけが元のエンティティを参照しています。再帰的なコードは分かりません。簡素化する必要があります

私は、元のエンティティを取得するために再帰を使用していますが、コードはその読めない

private static PermanentPlacement PopulatePermanentPlacement(InvoiceLine invoiceLine) 
     { 
      PermanentPlacement permanentPlacement; 
      var creditReissue = invoiceLine.CreditReissue; 
      do 
      { 
       permanentPlacement = creditReissue.InvoiceLine.PermanentPlacement; 
       if (permanentPlacement == null) 
       { 
        creditReissue = creditReissue.InvoiceLine.CreditReissue; 
       } 
      } while(permanentPlacement == null); 

      return permanentPlacement; 
     } 

は、私はこれを読みやすくし、簡素化することができます方法はありますか?

+10

ここでは実際に再帰を使用していません。 – Servy

+3

ですが、コードは再帰的ではありません –

+4

これは再帰ではありません。 –

答えて

5

私はRenéVogtの答えがこのコードを単純化する最良の方法だと思います。しかし、他にもあります。

static IEnumerable<Reissue> CreditReissues(Reissue original) 
{ 
    var current = original; 
    while(true) 
    { 
    yield return current; 
    current = current.InvoiceLine.CreditReissue; 
    } 
} 

そして今、あなたは信用再発行の無限列を使用するために、再びループを記述する必要はありません:たとえば、ヘルパー関数にループを移動することを検討して

private static PermanentPlacement PopulatePermanentPlacement(
    InvoiceLine invoiceLine) 
{ 
    return CreditReissues(invoiceLine.CreditReissue) 
    .Select(cr => cr.InvoiceLine.PermanentPlacement) 
    .First(pp => pp != null); 
} 

つまり、無限のクレジット再発行のシーケンスを取り、それを永久配置の無限のシーケンスに変換し、最初の非ゼロのシーケンスをシーケンスに戻します。シーケンスにループを変更することで、我々は今、私たちはシーケンス文と変数のレベルでないのレベルにを実行する操作を記述することができますどのように

注意してください。

ちなみに、元のコードで再帰を使用していますが、そうではありません。再帰的な解決策は次のようになります。

private static PermanentPlacement PopulatePermanentPlacement(
    InvoiceLine invoiceLine) 
{ 
    return invoiceLine.PermanentPlacement ?? 
     PopulatePermanentPlacement(
      invoiceLine.CreditReissue.InvoiceLine); 
} 

あなたはC#が末尾再帰であることが保証されていないため、潜在的に無限のループのための再帰的なソリューションを使用するべきではありませんので、スタックを吹くことができます。

2

私はコードを短くします:

private static PermanentPlacement PopulatePermanentPlacement(InvoiceLine invoiceLine) 
{ 
    var creditReissue = invoiceLine.CreditReissue; 
    while(creditReissue.InvoiceLine.PermanentPlacement == null) 
     creditReissue = creditReissue.InvoiceLine.CreditReissue; 

    return creditReissue.InvoiceLine.PermanentPlacement; 
} 

これは、最終的なInvoiceLinePermantPlacement余分な時間にアクセスすることを除いて、あなたのコードと同じように行います。したがって、このプロパティゲッターが値を返すだけではなく、この変更が有効でない場合もあります。

-2

あなたのコードはかなりわかりやすく、わかりやすいようです。ルネ・フォークトの答えはあなたがロジックを変更せずにそれを作ることができると同じくらい短いですが、私は本当にこのかもしれない何をしたいという直感を持っている:

private static PermanentPlacement PopulatePermanentPlacement(InvoiceLine invoiceLine) 
{ 
    var creditReissue = invoiceLine.CreditReissue; 
    while (creditReissue.InvoiceLine.CreditReissue != null) 
    { 
     // Get the last credit reissue 
     creditReissue = creditReissue.InvoiceLine.CreditReissue; 
    } 
    return creditReissue.InvoiceLine.PermanentPlacement;  
} 

それはロジックを少し変更し、それことを確認してください同等です。

関連する問題