【问题标题】:Map enum value robustly稳健地映射枚举值
【发布时间】:2013-05-15 09:55:27
【问题描述】:

我有一个表单,用于从用户那里收集数据。收集这些数据时,我将其传递给各个合作伙伴,但是每个合作伙伴对每条数据都有自己的规则,因此必须对其进行转换。我可以做到这一点,但我担心的是稳健性。这是一些代码:

首先,我有一个枚举。这被映射到下拉列表 - 描述是文本值,而 int 映射到值。

public enum EmploymentStatusType
{
    [Description("INVALID!")]
    None = 0,
    [Description("Permanent full-time")]
    FullTime = 1,
    [Description("Permanent part-time")]
    PartTime = 2,
    [Description("Self employed")]
    SelfEmployed = 3
}

提交表单时,选定的值会转换为正确的类型并存储在另一个类中 - 属性如下所示:

    protected virtual EmploymentStatusType EmploymentStatus
    {
        get { return _application.EmploymentStatus; }
    }

对于拼图的最后一位,我将值转换为合作伙伴所需的字符串值:

    Dictionary<EmploymentStatusType, string> _employmentStatusTypes;
    Dictionary<EmploymentStatusType, string> EmploymentStatusTypes
    {
        get
        {
            if (_employmentStatusTypes.IsNull())
            {
                _employmentStatusTypes = new Dictionary<EmploymentStatusType, string>()
                {
                    { EmploymentStatusType.FullTime, "Full Time" },
                    { EmploymentStatusType.PartTime, "Part Time" },
                    { EmploymentStatusType.SelfEmployed, "Self Employed" }
                };
            }

            return _employmentStatusTypes;
        }
    }

    string PartnerEmploymentStatus
    {
        get { return _employmentStatusTypes.GetValue(EmploymentStatus); }
    }

我调用 PartnerEmploymentStatus,然后返回最终的输出字符串。

有什么想法可以使它更健壮吗?

【问题讨论】:

  • 您认为什么是“非稳健”?
  • 我担心的是,如果/当枚举更改/增长 - 并且有可能因为新合作伙伴可能有不同的规则需要适应,那么所有其他类都包含需要的映射被改变和休息。如果我有 30 个合作伙伴,这可能会成为一项艰巨的任务。
  • 那你需要重构为一个翻译区。可能类似于访问者模式的实现。您的选择是分发代码(就像您现在所做的那样)或将其集中的访问者。您需要建立一定程度的脆弱性,以便您的覆盖测试在您扩展时会显示问题,以迫使您正确维护代码。您处于一个相当普遍的困境中,这实际上是一个代码组织。
  • @JohnNicholas - 感谢访问者模式的建议 - 查了一下,这正是我正在做的。有时保证是正确的答案。
  • 那么不好让它成为一个答案;p 同意保证,我发现这里越来越多的问题只是在测试我自己与他人的理智。 “嗨,我有一个我认为没有答案的问题,有人可以给我一个对我有帮助的答案吗?”

标签: c# asp.net enums


【解决方案1】:

然后你需要将它重构为一个翻译区域。可能类似于访问者模式的实现。您的选择是分发代码(就像您现在所做的那样)或将其集中的访问者。您需要建立一定程度的脆弱性,以便您的覆盖测试在您扩展时会显示问题,以迫使您正确维护代码。您处于一个相当普遍的困境中,这实际上是一个代码组织的困境

【讨论】:

    【解决方案2】:

    我确实在我的一个项目中遇到过这样的问题,我通过使用辅助函数和资源名称约定来解决它。

    功能就是这个:

        public static Dictionary<T, string> GetEnumNamesFromResources<T>(ResourceManager resourceManager, params T[] excludedItems)
        {
            Contract.Requires(resourceManager != null, "resourceManager is null.");
    
            var dictionary =
                resourceManager.GetResourceSet(culture: CultureInfo.CurrentUICulture, createIfNotExists: true, tryParents: true)
                .Cast<DictionaryEntry>()
                .Join(Enum.GetValues(typeof(T)).Cast<T>().Except(excludedItems),
                    de => de.Key.ToString(),
                    v => v.ToString(),
                    (de, v) => new
                    {
                        DictionaryEntry = de,
                        EnumValue = v
                    })
                .OrderBy(x => x.EnumValue)
                .ToDictionary(x => x.EnumValue, x => x.DictionaryEntry.Value.ToString());
            return dictionary;
        }
    

    约定是在我的资源文件中,我将具有与枚举值相同的属性(在您的情况下为 NonePartTime 等)。这是在帮助函数中执行Join 所必需的,您可以根据需要进行调整。

    所以,每当我想要一个枚举值的(本地化)字符串描述时,我都会调用:

    var dictionary = EnumUtils.GetEnumNamesFromResources<EmploymentStatusType>(ResourceFile.ResourceManager);
    var value = dictionary[EmploymentStatusType.Full];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-14
      相关资源
      最近更新 更多