修改string.Substring

时间:2013-12-14 18:09:49

标签: c# string substring extension-methods

10次中的9次,当我想在字符串上使用Substring()方法时,这是因为我想要从字符串的END中删除一些字符,而不是开头。虽然默认的Substring确实支持这一点,但它是通过获取第二个参数来实现的,该参数是所需字符串的长度,而不是端点。这意味着如果我一直想要从一系列不同长度的字符串中删除N个字符,我必须做一个额外的步骤,这可以产生更多的代码。举个例子:

//Shaving the first N chars
string trimmed = foo.bar.widget.GetType().Name.Substring(N);

VS

//Shaving the last N chars
string trimmed = foo.bar.widget.GetType().Name.Substring(0, foo.bar.widget.GetType().Name.Length - N);

或者可能要保存额外的函数调用,请使用第二行:

string name = foo.bar.widget.GetType().Name;
string trimmed = name.Substring(0, name.Length - N);

无论哪种方式,你基本上都会将字符串末尾的字符数量增加一倍而不是开头。我的修改很简单。如果你传递一个负N(否则会没有意义),它会在字符串末尾而不是开头处削掉-N个字符。我已经可以使用扩展方法对其进行编码:

public static string MySubstring(this string str, int val)
{
    return (val > 0) ? str.Substring(val) : str.Substring(0, str.Length + val);
}

然后当我想要削掉最后的N个字符时,我就这样做了:

string trimmed = foo.bar.widget.GetType().Name.MySubstring(-N);

简短又甜蜜,就像剃掉开头的人物一样。我的问题是 - 是否可以覆盖默认的Substring()函数的行为,这样我就可以这样做,而不必使用我自己的函数唯一名称?它不会使任何现有代码无效,因为以前没有理由将它传递给负数,这样做只会引发异常并崩溃。这只是那些简单的严肃的功能之一,感觉它应该是开始实现的一部分。

2 个答案:

答案 0 :(得分:4)

根据C#文档,you can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called.所以答案是“否”。

可以说,这是一件好事,因为否则你的代码会变成一个噩梦,可以读给不熟悉你的扩展的人。

注意:str.Substring(0, str.Length + val);可以替换为str.Remove(str.Length + val)

答案 1 :(得分:3)

您无法使用扩展方法在严格意义上覆盖字符串上的方法,因为在编译方法调用时,编译器将始终在具有相同签名的扩展方法上选择实例方法。但是,您可以使用命名参数实现接近您想要的功能。这也应该有助于避免可读性问题。这是一个例子

public static string Substring(this string @this, int trimFromEnd)
{
    return @this.Substring(0, @this.Length - trimFromEnd);
}

// if you do
"abc".Substring(1) -> returns "bc"

// if you do
"abc".Substring(trimFromEnd: 1) -> returns "ab"

就个人而言,我发现这比Substring(-1)或者只是Substring(varName)更具可读性,其中varName恰好是负数。