【问题标题】:How Would I write a String.Format Extension Method?我将如何编写 String.Format 扩展方法?
【发布时间】: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,它有很多重载,因为有很多方法可以调用它。

嗯……这让事情变得复杂了。

是否有一种简单的方法来编写 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 重载,但这可能不是必需的。

【问题讨论】:

    标签: c# string extension-methods


    【解决方案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 好点。这对于支持/重构旧代码库可能不会那么有用。但它非常适合新项目。
      猜你喜欢
      • 2018-02-23
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 2011-05-07
      • 1970-01-01
      相关资源
      最近更新 更多