【问题标题】:wrap dictionary for readability?包装字典以提高可读性?
【发布时间】:2018-03-20 23:39:11
【问题描述】:

我正在构建一个翻译器,它将翻译保存在字典中,其中第一个字符串是标识符,第二个字符串是翻译后的字符串。

在我看来,字典语法不是很可读,所以我正在考虑像这样包装我的字典

class Translation : Dictionary<string,string>{}

然后也是键值对

class SingleTranslation : KeyValuePair<string,string>

但是 KeyValuePair 类是密封的(不能被继承)。有人对如何使我的字典更具可读性有任何建议吗?

我最大的担心是当我不得不遍历字典时

foreach(KeyValuePair<string,string> kvp in _translation)
{
    string whatever = kvp.Value;
    do stuff...
    if(kvp.key)
        do stuff..
}

我当然可以在 foreach 中创建一个称为 Identifier 的字符串并将其设置为等于 kvp.key。但我更喜欢类似的东西

foreach(SingleTranslation singleTranslation in _translation)
{
    singleTranslation.Identifier ... do stuff...
}

【问题讨论】:

  • “环绕”——这听起来像是作曲。您可以创建一个由字典支持的类,并通过底层字典公开您想要的功能
  • 如果你使用var,大部分噪音都会消失。 foreach (var kvp in _translation) ...并且IdentifierKey 好得多,其他阅读您的代码的人会理解吗?另外,您为什么要遍历整个字典?如果您访问模式主要是顺序的,只需使用List&lt;SingleTranslation&gt;。如果您真的关心大小和速度,您可以使用 TernaryTree 代替,这是许多单词词典使用的。
  • “更具可读性”对您意味着什么?
  • @Dennis Kuypers:当然,通过一些额外的工作,我可以使它与迭代器一起工作,并重载 [] 运算符..
  • @Ian Mercer:我同意 key 和 identifier 是可互换的词,在这种情况下它们都很好。我正在遍历整个字典,因为我将它发送到一个嵌入式软件单元。我认为我的查找功能将来会很方便,这就是我选择字典的原因

标签: c# dictionary readability


【解决方案1】:

不要那样做。直接使用Dictionnary 进行完全访问,或者如果您想要更多控制权则使用组合。

还在 foreach 循环中使用var。为此定义自定义类型没有任何价值(当您尝试将 KeyValuePair 转换为派生类时,它甚至不应该工作。顺便说一句,这是它被密封的原因之一。

如果您真的想使用自定义类型,并且不想编写太多自定义代码,那么也许这样的方法对您有用:

class Translation
{
    public Dictionary<string,string> Data { get } = new Dictionary<string,string>;
}

那么你可以这样做:

Translation t; // Fill some data...
foreach (var item in t.Data) { … }

这样,您可以确保在为每种情况使用不同类型时不会将不正确的字典传递给函数:

void DisplayTranslation(Translation t) { … }

如果您愿意,您可以改进您的 Translation 类,使其不公开内部字典,而是公开适当的成员、属性和接口以用于所需用途。

【讨论】:

    【解决方案2】:

    你总是可以使用字典以外的东西,比如从 List 继承的类,然后在上面添加一个索引器,这样你仍然可以使用像 translations["myIndex"] 这样的语法。下面的代码可以优化,但你可以理解。

    public class Translations : List<SingleTranslation>
    {
        public SingleTranslation this[string identifier]
        {
            get
            {
                return this.FirstOrDefault(p => p.Identifier == identifier);
            }
            set
            {
                SingleTranslation translation = this.FirstOrDefault(p => p.Identifier == identifier);
                if (translation == null)
                {
                    this.Add(value);
                }
                else
                {
                    translation.Value = value.Value;
                }
            }
        }
    }
    
    public class SingleTranslation
    {
        public SingleTranslation(string identifier, string value)
        {
            Identifier = identifier;
            Value = value;
        }
    
        public string Identifier { get; set; }
        public string Value { get; set; }
    }
    

    示例用法:

    public class Program
    {
        public static void Main()
        {
            Translations translations = new Translations();
            translations.Add(new SingleTranslation("hello", "hola"));
            translations.Add(new SingleTranslation("day", "día"));
            foreach(SingleTranslation translation in translations)
            {
                Console.WriteLine("{0}: {1}", translation.Identifier, translation.Value);
            }
    
            translations["hello"].Value = "salut";
            translations["day"].Value = "jour";
    
            foreach(SingleTranslation translation in translations)
            {
                Console.WriteLine("{0}: {1}", translation.Identifier, translation.Value);
            }                
        }
    }
    

    fiddle 中有一个工作示例:

    【讨论】:

      【解决方案3】:

      如果可读性只是您的问题,您可以在命名空间声明中为其设置别名。

      using SingleTranslation = KeyValuePair<string,string>;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-10
        • 1970-01-01
        • 2019-08-13
        • 1970-01-01
        • 2010-09-08
        • 2022-01-22
        • 1970-01-01
        • 2011-07-11
        相关资源
        最近更新 更多