我将如何编写 String.Format 扩展方法?
Posted
技术标签:
【中文标题】我将如何编写 String.Format 扩展方法?【英文标题】:How Would I write a String.Format Extension Method? 【发布时间】:2013-05-17 14:55:04 【问题描述】:我在 C# 代码中使用String.Format 可能比if
语句之外的任何东西都多。
string ask = String.Format("Continue using [0]?", value);
我刚刚开始考虑我使用它的频率。
接下来,我开始思考为它创建一个Extension Method 会有多棒。
ask.Format("Continue using [0]?", value);
所以,我查看了String.Format,它有很多重载,因为有很多方法可以调用它。
Format(String, Object) Format(String, Object[]) Format(IFormatProvider, String, Object[]) Format(String, Object, Object) Format(String, Object, Object, Object)嗯……这让事情变得复杂了。
是否有一种简单的方法来编写 Extension Method 以简单地构建在 System.String
命名空间中已经存在的重载之上?
这是我想看到的:
public static class Extensions
public static String Format(this String str, String formatText, /* What goes here? */)
return str.Format(formatText, /* Magic */);
我想我可以编写一个重载来匹配每个 String.Format 重载,但这可能不是必需的。
【问题讨论】:
【参考方案1】:ask.Format("Continue using [0]?", value);
不是我会使用它的方式。这就是我要做的:
var ask = "Continue using [0]?".FormatWith(value);
这是我的扩展方法:
public static string FormatWith(this string value, params object[] args)
return String.Format(value, args);
【讨论】:
迈克,我稍微编辑了你的代码以包含formatText
字符串。否则,这就像我想要的那样工作。
我应该把那个方法放在哪里
在您的项目/解决方案中任何位置的静态类中:msdn.microsoft.com/en-us/library/bb383977.aspx【参考方案2】:
您想修改调用字符串。你不能那样做。 .Net 中的字符串不会改变(它们是不可变的),因此您仍然必须返回一个新字符串。您可以从 C# 获得的最接近的代码是这样的:
string ask = $"Continue using [value]?";
如果您可以通过引用传递扩展对象,则可以修改您的原始字符串。不幸的是,C# 不支持这一点。
有趣的是IL确实支持它,你可以使用VB.Net编写你想要的方法:
<Extension()> _
Public Shared Sub Format(ByRef str As String, ByVal formatText As String, ByVal ParamArray args As Object())
str = String.Format(formatText, args);
End Sub
不幸的是,即使您将其填充到 VB.Net 类库项目中,您也无法从 C# 调用它,因为 C# 要求您在调用函数时在调用站点使用 ref
关键字参数通过引用,并且没有用于扩展方法的语法。
有关与您所需语法不完全匹配但仍会为您提供相当不错的解决方法,请参阅Mike Cole's answer。
【讨论】:
【参考方案3】:您很接近,只缺少params object[] args
参数:
public static class Extensions
public static String Format(this String str,
String formatText,
params object[] args)
return str.Format(formatText, args);
【讨论】:
这不是无限递归吗? 是的,但我很快就明白了他的意思。他可能只是使用了我未经测试的示例代码,这已经是无限递归的。【参考方案4】:使用字符串插值(在 C# 6.0 和 VS 2015+ 中)。您的代码如下所示:
var ask = $"Continue using [value]?";
在我发现字符串插值之前,我一直在使用 String.Format 或字符串连接,现在我被迷住了。
这样做的一个潜在缺点是您无法将格式字符串分解为常量或资源。在这里查看更多详细信息:
https://msdn.microsoft.com/en-us/library/dn961160.aspx
本文介绍了更多详细信息,并包含了其他一些不错的宝石。 Definitley 值得一读:
https://msdn.microsoft.com/en-us/magazine/dn879355.aspx
【讨论】:
公平地说,自 VS 2015 以来,我们只能在 C# 中执行此操作,因此有 很多 旧代码没有使用它. @IanMcLaird 好点。这对于支持/重构旧代码库可能不会那么有用。但它非常适合新项目。以上是关于我将如何编写 String.Format 扩展方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 Lua 中 string.format 参数不正确抛出异常问题
string.format(format,doubleValue) ,精度丢失
如何在 Scala 中使用 java.String.format?