序列化可本地化字符串

本文关键字:字符串 本地化 序列化 | 更新日期: 2023-09-27 18:18:52

是否有方便的方法序列化对存储在资源中的字符串的引用。Resx文件(多种语言)。我想稍后访问它(在应用程序可能已经重新启动之后),并以当前活动的语言显示它。

另一个用例是将"资源条目"传递给某个方法,例如显示一条错误消息(用当前活动的语言),同时用英语记录该消息(以便我们可以调试它)。

要记住的一点是,我们并不是只有一个资源。(在这种情况下,我们可以简单地存储Key并使用ResourceManager实例),但是在复合应用程序中有大量的Key。

有多个用例:一个目的是避免不必要的代码重复。写像ShowMessage(messageKey)这样的东西(它显示消息并记录它)比写

要方便得多。
ShowMessage(Resources.ResourceManager.GetString("Key", CultureInfo.CurrentCulture));
Log(Resources.ResourceManager.GetString("Key", CultureInfo.InvariantCulture));

设置一些局部异常也很有用(这样组件就不必知道关于ShowMessage方法的任何信息)。

在我的情况下,我有一些可序列化的CNC宏,其中我想要有一些可本地化的消息步骤(用户必须在继续之前执行一些手动操作)。在配置宏和执行宏时,语言可能会有所不同。

序列化可本地化字符串

您可以考虑一些观察者模式的变体,比如使用事件来显示和记录消息的第三方连接。它涉及将以下内容提取到所有程序集使用的低级共享DLL中:

public class UIMessageEventArgs : EventArgs
{
    public string Key { get; private set; }
    public Func<CultureInfo, string> GetString { get; private set; }
    public UIMessageEventArgs(string key, Func<CultureInfo, string> getString)
    {
        if (key == null || getString == null)
            throw new ArgumentNullException();
        this.Key = key;
        this.GetString = getString;
    }
}
public interface IUIMessageService
{
    event EventHandler<UIMessageEventArgs> OnMessage;
    void ShowMessage(object sender, string key, Func<CultureInfo, string> getString);
}
public sealed class UIMessageService : IUIMessageService
{
    static UIMessageService() { instance = new UIMessageService(); }
    static UIMessageService instance;
    public static UIMessageService Instance { get { return instance; } }
    UIMessageService() { }
    #region IUIMessageService Members
    public event EventHandler<UIMessageEventArgs> OnMessage;
    public void ShowMessage(object sender, string key, Func<CultureInfo, string> getString)
    {
        if (getString == null)
            throw new ArgumentNullException("getString");
        if (key == null)
            throw new ArgumentNullException("key");
        var onMessage = OnMessage;
        if (onMessage != null)
            onMessage(sender, new UIMessageEventArgs(key, getString));
    }
    #endregion
}
public static class UIMessageExtensions
{
    public static void ShowMessage(this ResourceManager resourceManager, string key)
    {
        if (resourceManager == null)
            throw new ArgumentNullException("resourceManager");
        if (key == null)
            throw new ArgumentNullException("key");
        UIMessageService.Instance.ShowMessage(resourceManager, key, c => resourceManager.GetString(key, c));
    }
}

我将消息服务设置为单例,因为我怀疑您的所有侦听器都将是单例的。

然后在CNC代码中,您只需调用:

Resources.ResourceManager.ShowMessage("Key");

此外,在c# 6.0中,您应该能够使用nameof来代替硬编码的属性名称字符串:

Resources.ResourceManager.ShowMessage(nameof(Resources.Key));
顺便说一下,如果您正在实现CAD/CAM相关的宏功能,您可能会考虑记录键字符串而不是不变消息-然后将不变消息作为注释添加到宏中。这样,即使在不变语言中,宏也不会因消息文本的更改(拼写修复)而意外失效。

如果在某些时候需要能够将来自用户的响应记录到宏中,该宏可选地(根据宏作者的意愿)中断交互响应,则可以扩展UIMessageService模型,以允许通过要注入的消息键返回用户响应的委托。