returns 字符串函数结果的字符串插值

String interpolation on the result of a function that returns string

我有一个函数可以从 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 ?

有什么办法吗?

如果可以将美元符号放在任何字符串(无论是变量、字符串还是函数)的前面来进行字符串插值,那就太好了。

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

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

你不能那样做。

字符串插值部分是编译器的魔法,您不能将字符串插值注入普通字符串。由于您无法更改 Translate 方法,它仍将是 return 一个字符串,因此您必须自己做。

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


现在,如果 all 是事物的名称,而不是 returned 字符串中的 expressions,那么你可以自己做。换句话说,您展示的确切示例不应该 难。但是,它仍然不会是 "string interpolation" 这样的,这将是你自己的事情。换句话说,如果 returned 字符串曾经包含类似 ".... {firstname:-40} ..." 的内容,那么您的旅程就很艰难了。

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

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

如果可以将变量转换为匿名(或定义的对象),则可以使用 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);

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