pal*_*ain 11 c# generics dictionary
在C#struct中,我们可以通过它的名称清楚地知道变量的用途.例如,
public struct Book
{
public string title;
public string author;
}
Run Code Online (Sandbox Code Playgroud)
然后,我知道b.title是一种字符串,它指的是标题.
但是在C#字典中,我们只能指定类型
Dictionary<string,string> d
Run Code Online (Sandbox Code Playgroud)
我如何使代码更具可读性,使得字典的键是字符串的类型,它是指标题,值是字符串的类型,它指的是作者?这意味着,其他人在阅读代码时很容易知道d ["JRR Tolkien"]是字典的错误用法.
编辑 @mike z建议使用变量名titleToAuthor来帮助提高可读性.但我真正的问题是在代码中有嵌套字典.例如
Dictionary<string, Dictionary<string, string>>,
or even 3 levels
Dictionary<string, Dictionary<string , Dictionary< string , string[] >>>.
Run Code Online (Sandbox Code Playgroud)
我们希望在不创建自己的类的情况下保持使用Dictionary的便利性,但同时我们需要一些方法来提高可读性
小智 16
在 .NET 6 和 C# 10 中,您现在可以使用global using指令在项目中提供类型别名。
将内置类型的别名放在一处,例如GlobalUsings.cs.
global using Title = System.String;
global using Author = System.String;
Run Code Online (Sandbox Code Playgroud)
然后使用别名来提高词典的可读性。
Dictionary<string, Dictionary<Title, Author>>
Run Code Online (Sandbox Code Playgroud)
cho*_*mba 11
正如@ScottDorman所建议的那样,您可以定义一个TitleAuthorDictionary派生自的新类型Dictionary<string, string>,如下所示:
public class TitleAuthorDictionary : Dictionary<string, string>
{
public new void Add(string title, string author)
{
base.Add(title, author);
}
public new string this[string title]
{
get { return base[title]; }
set { base[title] = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用更易读的Dictionary Collection,如下所示:
TitleAuthorDictionary dictionary = new TitleAuthorDictionary();
dictionary.Add("Title1", "Author1");
dictionary.Add(title: "Title2", author: "Author2");
dictionary["Title2"] = "Author3";
Run Code Online (Sandbox Code Playgroud)
小智 6
如果不与语言作斗争就无法解决的问题,我建议使用文档解决。标识符作为自我文档的一种形式包含在该类别中。
因此,要将自我文档添加到此类类型中:
using TitleToAuthor = System.Collections.Generic.Dictionary<
string, // title
string // author
>;
Run Code Online (Sandbox Code Playgroud)
向该类型的实例添加自文档:
TitleToAuthor title_to_author = new TitleToAuthor();
Run Code Online (Sandbox Code Playgroud)
不幸的是,您不能嵌套 using 指令作为泛型类型参数,因此使用这样的解决方案将使您的 using 指令位于文件顶部的丑陋,但至少编写一次的那个丑陋的代码将创建一个非常可读的左侧的别名(准确显示它的用途),您可以在整个代码的其余部分中引用它,而无需实际创建新的数据类型。
另一种方法是简单地创建新的数据类型,从字典继承,例如,如果您可以使用新类型做更多的事情,而不是简单地获得更易读的类型名称,例如添加对此特别有用的方法,我会建议使用这条路线集合,或者如果该集合在许多源文件中使用(从那时起您必须重复使用相同的指令很多)。
在这种情况下,组合可能比继承(将字典存储为成员)更好,因为这样您就可以创建一个更小的、根据您的需要量身定制的子集接口(并且可能通过仅提供更高级的函数来减少滥用它的方法)特定容器类型的全部意义),而不仅仅是完整的字典界面+更多方法。在这种情况下,您会将有点难以阅读的通用通用字典转换为某些内容的隐藏实现细节,不仅在类型名称方面可读性更好,而且还提供了更小的、量身定制的(不太通用)界面,更具体地处理您的需求。对于一个简单的示例,允许为键或值指定空字符串可能是错误的。字典不会强加这样的断言,
如果您对字典的键/值参数的可读性感到困惑,那么问题可能不在于字典的可读性,而在于特定字典的公开曝光量。如果您有一个字典实例或什至具有非常公开的可见性并在所有地方都被引用的类型,那么您可能不仅关心此类代码的可读性,还关心允许访问它的人做他们想做的任何事情的灵活性在完整的字典中允许(包括您可能不希望在更广泛的范围内发生的事情)。毕竟,即使是像这样的类型float很少告诉你它应该做什么,但我们倾向于以这样的方式编写代码,其中浮点数要么是类/函数的实现细节,要么只是函数参数/返回类型,就它们的作用而言,它们是相当明显的。因此,也许最好让这些字典不那么明显,而更多地融入私有实现细节中,因为实现细节的清晰度和可读性通常不如接口中更公开可见的部分那么重要可以在整个代码库中访问。
| 归档时间: |
|
| 查看次数: |
5769 次 |
| 最近记录: |