【问题标题】:String interpolation into a variable字符串插值到变量中
【发布时间】:2017-07-21 11:05:50
【问题描述】:

我正在尝试使用 c# 6.0 中的字符串插值将人名作为动态值插入到电子邮件正文中。

概念证明

public class Program
{
    public static void Main()
    {
        var p = new Person { FirstName = "John", LastName = "Smith" };
        var msg = $"{p.FirstName} says 'Hello World!'";
        
        Console.WriteLine($"Message: {msg}");
    }
}
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

这个概念证明输出字符串:

消息:John 说“Hello World!”

实施

所以现在当我尝试使用这个概念来构建我的 MailMessage 时,我在电子邮件中收到了{Contact.FirstName} 输出。代码如下:

private string _Body;
public string Body
{
    get { return _Body; }
    set
    {
        _Body = value;
        RaisePropertyChangedEvent("Body");
    }
}

var Contacts = Context.Contacts
  .Where(x => x.ContactGroupId == ContactGroupId && x.Deleted == false);

// By this point, Body will already have a value containing the interpolation.
// For example: Body = "Message: {Contact.Name} says \"Hello World!\"";
foreach (var Contact in Contacts)
{
    MailMessage Msg = new MailMessage();
    
    MailMessage.Body = ${Body}
}

问题

这应该将正文呈现为:

消息:John 说“Hello World!”

相反,渲染的是:

消息:{Contact.FirstName} 说“Hello World!”

如果我实际上并未在代码中对字符串进行硬编码,如何将变量插入到字符串中?

【问题讨论】:

  • 字符串插值是一个编译时特性。它不能用于在运行时替换令牌。
  • 你的代码甚至不应该编译。
  • 应该是MailMessage.Body = $"{Body}"...

标签: c#


【解决方案1】:

${Body} 无法编译。

您不能在运行时生成插值,它是一种语法糖,编译器会将其转换为String.Format

您可以使用StringBuilderString 中的Replace 来解决您的问题:

sb.Replace("{p.FirstName}", p.FirstName);

【讨论】:

  • String.Format 没问题,但不会有同样的问题吗?无论如何,当用户写电子邮件时,我不能让用户在邮件正文中输入 {0} {1} 等标签......假设我总是可以将其保留为 {Contact.FirstName} 然后 .Replace() 他妈的它...
  • @Ortund 是的,这就是你需要做的,不过我建议使用StringBuilder
  • @Ortund 您可以通过多种方式解决您的问题,String.Replace 是其中一种选择。 String.Replace("{p.FirstName}", p.FirstName); StringBuilder 是一个更好的选择。
  • 我想无论哪种方式,插值问题现在都没有实际意义,因此接受答案成为一个奇怪的问题
  • @Ortund 实际上这是一个有效的问题,我相信其他人也有同样的问题。
【解决方案2】:

字符串插值是一个编译时特性。这就是为什么你可以do some neat things like

Console.WriteLine($"When {condition} is true, {(condition ? "it's true!" : "It's False")}");

您实际上是在将 C# 代码放入字符串中

但是,如果它被实现为一个动态功能,您可以在其中加载字符串并让它们在运行时进行评估,那么您将面临安全风险,就像在 JavaScript 中使用 eval 一样。那么,你想做的事不可能做是有道理的。

【讨论】:

    猜你喜欢
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多