簡體   English   中英

Linq代碼重構

[英]Linq code refactoring

請幫助我使用Linq重構此代碼。 如何只使用一次Where和ToList? 尋求幫助

private IEnumerable<SomeClass> Filter(IEnumerable<SomeClass> aaa, string name, string company, string address,int? age)       
{
    var ans = new List<SomeClass>();         
    if (!String.IsNullOrEmpty(name))
        ans = aaa.Where(x => x.name.equal(name)).ToList();

    if (!String.IsNullOrEmpty(company))
        ans = ans.Where(x => x.company.equal(company)).ToList();

    if (!String.IsNullOrEmpty(address))
        ans = ans.Where(x => x.address.equal(address)).ToList();

    if (age.HasValue)
        ans = ans.Where(x => x.age == age.Value).ToList();

    return ans;
}

您可以使用此:

var ans = aaa.Where( x => ( string.IsNullOrEmpty(name)
                            || x.name.equal(name)
                          )
                          &&
                          ( string.IsNullOrEmpty(company)
                            || x.company.equal(company)
                          )
                          &&
                          ( string.IsNullOrEmpty(address)
                            || x.address.equal(address)
                          )
                          &&
                          ( !age.HasValue
                            || x.age == age.Value
                          )
                   );

您可以放棄對ToList所有呼叫。 沒有這些調用,組合過濾將以您不需要關心的延遲方式執行。

如果您確實想影響執行過濾的時間(或確保結果基於調用Filteraaa的快照,並且在以后更改aaa不改變),請將最后一行更改為

return ans.ToArray();

(這里可能不需要列表;無論如何,返回值都鍵入IEnumerable<SomeClass> ,並且調用者不應期望能夠直接修改(添加/刪除項)返回的對象。

因此,完整的代碼如下所示:

private IEnumerable<SomeClass> Filter(IEnumerable<SomeClass> aaa, string name, string company, string address,int? age)       
{
    IEnumerable<SomeClass> ans = new SomeClass[0];
    if (!String.IsNullOrEmpty(name))
        ans = aaa.Where(x => x.name.Equals(name));

    if (!String.IsNullOrEmpty(company))
        ans = ans.Where(x => x.company.Equals(company));

    if (!String.IsNullOrEmpty(address))
        ans = ans.Where(x => x.address.Equals(address));

    if (age.HasValue)
        ans = ans.Where(x => x.age == age.Value);

    return ans.ToArray();
}

正如其他答案所表明的那樣,也可以將所有Where調用合並到一個中,盡管堅持使用if s和Where s的原始鏈可以很清楚地顯示出它的作用,這對於合並的解決方案可能並非如此。

只是在這里添加另一個答案。 為什么在所有輸入中創建一個列表都是IEnumerable,所以輸出是否相同?

private IEnumerable<SomeClass> Filter(IEnumerable<SomeClass> aaa, string name, string company, string address, int? age)
{
    if (!String.IsNullOrEmpty(name))
        aaa = aaa.Where(x => x.name.Equals(name));

    if (!String.IsNullOrEmpty(company))
        aaa = aaa.Where(x => x.company.Equals(company));

    if (!String.IsNullOrEmpty(address))
        aaa = aaa.Where(x => x.address.Equals(address));

    if (age.HasValue)
        aaa = aaa.Where(x => x.age == age.Value);

    return aaa;
}

我在這個問題上的兩分錢:

  1. 我認為您不需要將方法簡化為一個Where子句,因為如果您以這種方式保留它,則以后可以輕松添加新的過濾器參數,並且您的代碼將易於閱讀。
  2. 您無需指定ToList()
  3. 取而代之的String.IsNullOrEmpty()考慮使用String.IsNullOrWhiteSpace() 這樣,如果提供了非空但空白的字符串,則不會過濾掉實體。
  4. 如果合適x.name.Equals(name, StringComparison.InvariantCultureIgnoreCase)考慮使用x.name.Equals(name, StringComparison.InvariantCultureIgnoreCase)代替x.name.Equals(name)

您可以執行以下操作:

var ans = aaa.Where(x => !string.IsNullOrEmpty(name) ? x.name.equal(name) : false).ToList()
             .Union(aaa.Where(x => !string.IsNullOrEmpty(company) ? x.company.equal(company) : false).ToList())
             .Union(aaa.Where(x => !string.IsNullOrEmpty(address) ? x.address.equal(address) : false).ToList());

ans = ans.Where(x => age.HasValue ? x.age == age.Value : true).ToList();

您應該嘗試這樣的事情:

private static IEnumerable<SomeClass> Filter(IEnumerable<SomeClass> aaa, string name, string company, string address, int? age)
{

        var ans = aaa.Where(x => !String.IsNullOrEmpty(name) ? x.Name.Equals(name) : true)
                 .Where(x => !String.IsNullOrEmpty(company) ? x.Company.Equals(company) : true
                     && !String.IsNullOrEmpty(address) ? x.Address.Equals(address) : true
                     && age.HasValue ? x.Age == age.Value : true);


        return ans;
} 

但是請注意,在您的代碼中,如果“ name”參數為空,則始終返回0個結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM