2009-05-22 90 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; 
} 
相关问题