You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何存储插值字符串模板?适配现有继承类场景

可行解决方案

方案一:自定义消息容器类(兼容现有代码,推荐)

这个方案通过创建同时支持string和FormattableString的容器类,修改基类的Message字段类型为该容器,实现无缝兼容所有现有赋值代码,同时捕获插值字符串模板。

步骤1:创建MessageContainer容器类

public class MessageContainer
{
    // 存储最终渲染后的字符串
    public string StringValue { get; }
    // 存储插值模板(仅当赋值为插值字符串时不为null)
    public FormattableString Template { get; }

    private MessageContainer(string value)
    {
        StringValue = value;
        Template = null;
    }

    private MessageContainer(FormattableString template)
    {
        StringValue = template.ToString();
        Template = template;
    }

    // 隐式转换:string自动转为MessageContainer
    public static implicit operator MessageContainer(string value)
    {
        return new MessageContainer(value);
    }

    // 隐式转换:插值字符串(FormattableString)自动转为MessageContainer
    public static implicit operator MessageContainer(FormattableString template)
    {
        return new MessageContainer(template);
    }

    // 隐式转换:MessageContainer自动转为string,兼容原有需要string的场景
    public static implicit operator string(MessageContainer container)
    {
        return container.StringValue;
    }
}

步骤2:修改BaseMessage的Message字段类型

将基类中的string Message字段改为MessageContainer类型的属性:

public class BaseMessage
{
    public MessageContainer Message { get; set; }
    // ...其他原有代码
}

步骤3:ProcessMessage无需修改

子类继承基类后,原有实例化代码完全不需要改动:

public class ProcessMessage : BaseMessage
{
    // ...原有代码
}

使用效果

三种赋值方式均正常工作,且能捕获插值模板:

// 插值字符串:Template会保存模板和参数
var msg1 = new ProcessMessage { Message = $"User {userId} logged in" };
// 普通字符串:Template为null
var msg2 = new ProcessMessage { Message = "System started" };
// 字符串变量:Template为null
var msg3 = new ProcessMessage { Message = customMessage };

// 获取模板示例
if (msg1.Message.Template != null)
{
    string formatTemplate = msg1.Message.Template.Format; // 输出 "User {0} logged in"
    object[] templateArgs = msg1.Message.Template.GetArguments(); // 输出 [userId]
    // 在这里实现模板存储逻辑
}

方案二:编译时代码批量修复(无法修改基类时使用)

如果无法修改BaseMessage的Message字段类型,可以用Roslyn编写代码分析器,批量将插值字符串的赋值替换为专用方法调用,从而捕获FormattableString:

步骤1:给ProcessMessage添加专用方法

public class ProcessMessage : BaseMessage
{
    public FormattableString MessageTemplate { get; private set; }

    public void SetMessage(FormattableString template)
    {
        MessageTemplate = template;
        Message = template.ToString();
    }
}

步骤2:用Roslyn工具批量修改代码

通过代码分析器自动将所有:

var ret = new ProcessMessage() { Message = $"Some info {param}" };

替换为:

var ret = new ProcessMessage();
ret.SetMessage($"Some info {param}");

普通字符串和变量赋值的代码保持不变。

这种方式无需修改运行时逻辑,仅通过编译时工具完成批量代码调整,适合无法修改基类的场景。


内容的提问来源于stack exchange,提问作者bleat interteiment

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:39:56