2009-05-22 87 views
6

因爲這是我在我看來,是非常有用的擴展方法的第一次嘗試,我只是想確認我要下去右路我的第一個擴展方法,可以寫得更好嗎?

public static bool EqualsAny(this string s, string[] tokens, StringComparison comparisonType) 
    { 
     foreach (string token in tokens) 
     { 
      if (s.Equals(token, comparisonType)) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 

調用由

if (queryString["secure"].EqualsAny(new string[] {"true","1"}, StringComparison.InvariantCultureIgnoreCase)) 
{ 
    parameters.Protocol = Protocol.https; 
} 

編輯:一些優秀的建議,通過我正在尋找的東西。由於

編輯:

我已經決定對下列實施

public static bool EqualsAny(this string s, StringComparison comparisonType, params string[] tokens) 
{ 
    // for the scenario it is more suitable for the code to continue 
    if (s == null) return false; 

    return tokens.Any(x => s.Equals(x, comparisonType)); 
} 

public static bool EqualsAny(this string s, params string[] tokens) 
{ 
    return EqualsAny(s, StringComparison.OrdinalIgnoreCase, tokens); 
} 

我更喜歡使用PARAMS超過IEnumerable使用,因爲它簡化了調用代碼

if (queryString["secure"].EqualsAny("true","1")) 
{ 
    parameters.Protocol = Protocol.https; 
} 

相去甚遠上以前的

if (queryString["secure"] != null) 
{ 
    if (queryString["secure"] == "true" || queryString["secure"] == "1") 
    { 
     parameters.Protocal = Protocal.https; 
    } 
} 

再次感謝您!

+0

我個人認爲,想了解一下您的擴展方法的語法之前,你應該問一個初步的問題:你甚至想這個方法。首先,正如其他人所提到的那樣,它只是一個令牌倒置。任何(),其次,在您的使用示例中,您已經採用了一個簡單的概念,「這是一個真正的價值」,應該易於閱讀和替換它帶有一個涉及自定義擴展方法和即時數組的複雜表達式。國際海事組織,這些不必要的複雜性的小點加起來。 – tnyfst 2009-05-22 13:17:39

回答

5
public static bool EqualsAny(
    this string s, 
    StringComparison comparisonType, 
    params string[] tokens) 
{ 
    foreach (string token in tokens) 
    { 
     if (s.Equals(token, comparisonType)) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

使用參數,你不必首先強制你的字符串進入數組。

var match = "loool".EqualsAny(StringComparison.Ordinal, "hurf", "Durf"); 

的LINQ指明分數(JC +我)與NRE(框架標準):

public static bool EqualsAny(
    this string s, 
    StringComparison comparisonType, 
    params string[] tokens) 
{ 
    if(s == null) throw new NullReferenceException("s"); 
    return tokens.Any(x=> s.Equals(x, comparisonType)); 
} 
2

使您的tokens參數更一般 - 即使其爲IEnumerable<string>

而且,已經存在延伸IEnumerable<>的等效方法,例如, Any

public static bool EqualsAny(this string s, IEnumerable<string> tokens, StringComparison comparisonType) 
{ 
    return tokens.Any(t => s.Equals(t, comparisonType)); 
} 

此外,喬爾當然是正確的:你可能要執行的操作(防禦性編碼)之前檢查null值。這不是更安全,但它使本地化的錯誤更容易。爲了簡化EqualsAny的使用情況,您可以使用可變參數和默認策略 StringComparison

+0

@Joel:你是對的。我更一般地談論*任何*種錯誤處理。拋出`NullReferenceException`可能更合適。正如你所說:我們不知道這裏哪個行爲是首選。 – 2009-05-22 13:14:47

+0

呃,我的意思是`ArgumentNullException`。 – 2009-05-22 13:15:58

+0

我想說的是,它肯定不太安全,並且可能還難以本地化,因爲代碼可能在錯誤以可見方式出現之前長時間以無效的錯誤假設運行。拋出異常可能更合適,但我們無法知道寫入示例時OP需要哪種行爲。因此,不管好壞,偏見都是提供剛剛運行的代碼。 – 2009-05-22 13:16:45

1

public static bool EqualsAny(this string s, params string[] tokens) { 
    return EqualsAny(s, StringComparison.InvariantCultureIgnoreCase, tokens); 
} 

public static bool EqualsAny(this string s, 
          StringComparison stringComparison, 
          params string[] tokens) { 
    // your method 
} 

調用由

if (queryString["secure"].EqualsAny("true", "1")) { 
    parameters.Protocol = Protocol.https; 
} 
7

是的!首先,你需要檢查s爲空。此外,讓它接受禮物,而非只是一個陣列中的任何IEnumerable<string>,然後用其他LINQ運營商做的檢查:

public static bool EqualsAny(this string s, IEnumerable<string> tokens, StringComparison comparisonType) 
{ 
    if (s== null) return false; 
    return tokens.Any(t => s.Equals(t, comparisonType)); 
} 

思考如何處理是個null值,還有第三選項沒有人使用尚未:

public static bool EqualsAny(this string s, IEnumerable<string> tokens, StringComparison comparisonType) 
{ 
    if (s== null) return tokens.Any(t => t == null); 
    return tokens.Any(t => s.Equals(t, comparisonType)); 
} 

最後,關於您所選擇的實現:如果你將不得不重載,你可能也有IEnumerable的overloa ds以及你的params代碼調用這些。

3

另一種選擇是。這將簡化你的呼叫站點,因爲如果你有幾個字符串,你的匹配不需要在代碼中創建數組或列表。

public static bool EqualsAny(this string s,StringComparison comparisonType, param string[] tokens) 
{ 
    return EqualsAny(s,comparisonType,tokens); 
}  

public static bool EqualsAny(this string s,StringComparison comparisonType, IEnumerable<string>tokens)  
{ 
    //Throw nullReference to keep the semantics aligned with calling an instance member 
    if (s==null) throw new NullReferenceException();  
    foreach (string token in tokens)   
    {    
     if (s.Equals(token, comparisonType))    
     {     
      return true;    
     }   
    }   
    return false;  

} 
0

你在做什麼沒有什麼錯誤。然而,這種類型的功能已經以幾種不同的方式存在。

例子:

var candidates = List<SomeObject>(); 
if (candidates.Count(c=> string.Compare(c.PropertyValue, queryString["secure"], StringComparison.InvariantCultureIgnoreCase) == 0) > 0) 
{ 
parameters.Protocol = Protocol.https; 
} 
相關問題