【问题标题】:String interpolation on the result of a function that returns string返回字符串的函数结果的字符串插值
【发布时间】:2016-09-15 17:30:05
【问题描述】:

我有一个函数可以从这样的 xml 文件中获取一些文本:

var text = Translate("/foo/bar");

现在我想在 XML 中放入这样的字符串插值常量:

<foo>
  <bar>Hi, {firstName} {lastName}!</bar>
</foo>

所以,我想对翻译函数的结果进行字符串插值,类似于:

var firstName = "John";
var lastName = "Smith";
var formattedText = $Translate("/foo/bar");

但这似乎不起作用。 有什么办法可以解决这个问题,除了恢复为 string.Format 吗?

如果美元符号可以放在任何字符串的前面,无论是变量、字符串还是函数,都可以进行字符串插值。

值得一提的是,我无法控制翻译功能的代码,因为它位于第三方组件中。

【问题讨论】:

  • 有一些实用程序类是为这类事情编写的(例如,FormatWith)。然而,他们往往有无证的特质。这确实牺牲了对类型系统的保护,但这是运行时字符串格式化的固有缺点。

标签: c# string-interpolation


【解决方案1】:

不,你不能这样做。字符串插值在编译时执行。编译器检查插入的字符串文字,找到相关的格式字符串并将它们转换为{0} 等。在执行时执行此操作没有什么类似的。

【讨论】:

    【解决方案2】:

    你不能这样做。

    字符串插值是部分编译器魔法,您不能将字符串插值注入到普通字符串中。由于您无法更改 Translate 方法,它仍会返回一个字符串,因此您必须自己执行此操作。

    由于所有繁重的工作(查找表达式、提取表达式、重写实际字符串等)都是在编译时完成的,因此没有运行时类可以帮助您完成这些工作。


    现在,如果您拥有的 all 是事物的名称,而不是返回字符串中的 表达式,那么您可以自己执行此操作.换句话说,您展示的确切示例不应该难。但是,它仍然不是“字符串插值”,而是您自己的事情。换句话说,如果返回的字符串曾经包含类似 ".... {firstname:-40} ..." 的内容,那么您将面临一段艰难的旅程。

    最简单天真的解决方案是进行简单的字符串替换:

    var formattedText = $Translate("/foo/bar")
        .Replace("{firstname}", firstname)
        .Replace("{lastname}", lastname);
    

    【讨论】:

      【解决方案3】:

      如果您可以将变量转换为匿名(或定义的对象),则可以使用 SmartFormat (https://github.com/scottrippey/SmartFormat.NET)。

      var obj = new [MyClass - optional, if declared]
      {
          FirstName = "John",
          LastName = "Smith",
      }
      
      var formattedText = Smart.Format(Translate("/foo/bar"), obj);
      

      据我了解,您的代码不起作用的原因是,在编译期间而不是在运行时评估插值字符串(其中的变量)。

      【讨论】:

        猜你喜欢
        • 2016-08-26
        • 2021-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-20
        • 1970-01-01
        • 2017-05-05
        • 2011-12-30
        相关资源
        最近更新 更多