在这里进行广泛搜索后,我仍然需要专家建议:
要求
要求非常标准:将 int consts 映射到资源文件中的字符串,这样本地化就可以正常工作,我们可以轻松地为当前用户语言的下拉列表创建值对列表,以及对 int 值进行反向查找。const 整数在不同的类中被定义为静态的。
所以,这里是它目前的实施方式,有些事情告诉我它可以更好,值得批评:
字典类:
public class TLiteralDic : Dictionary<int, string>
{
//Lookup method
public string getLiteral(int key)
{
if (ContainsKey(key)) {
return this[key];
}
return string.Empty;
}
}
在靠近 UI 层的某个地方,填充下拉控件的扩展方法定义如下:
public static void fill(this TLiteralDic dic, DropDownList ddlst)
{
ddlst.Items.Clear();
foreach (KeyValuePair<int, string> v in dic) {
ddlst.Items.Add(new ListItem(v.Value, v.Key.ToString()));
}
}
添加对(静态 const int 到资源文件中的字符串):
public static class TLiterals
{
private static TLiteralDic _fileStatus;
public static TLiteralDic FileStatus
{
get
{
if (_fileStatus == null) {
_fileStatus = new TLiteralDic() {
{TFiles.Status.Cancelled, Lists.FileStatus_Cancelled},
{TFiles.Status.Closed, Lists.FileStatus_Closed},
{TFiles.Status.OnHold, Lists.FileStatus_OnHold},
{TFiles.Status.Open, Lists.FileStatus_Open},
{TFiles.Status.Pending, Lists.FileStatus_Pending},
{TFiles.Status.Portal, Lists.FileStatus_Portal}
};
}
return _fileStatus;
}
}
//... hundred of lists like that, short and long (up to 15 entries)
}
在代码中使用
抬头:
textStatus.Text = TLiterals.FileStatus.getLiteral(row.FileStatus);
清单填写:
TLiterals.FileStatus.fill(ddlstFileStatus);
注意事项
这个想法是只有一个定义映射的地方,并且能够从中创建一个列表或通过 int 值进行查找。理想情况下具有良好的性能、最小的内存占用和编码麻烦。
已经考虑过以下替代方案:
- 使用 switch (过去用于查找 - 大量冗余代码)
- 使用反射
- 关闭
- JSON、XML
- 在 VS2010 中使用 T4 类生成
到目前为止,还没有找到简单或明显更好的解决方案。
当前实施中的问题
- 围绕实际对列表的大量重复代码,理想情况下必须全部隐藏并重用
- 需要定义静态私有属性;这个想法是仅在第一次检索列表时才对列表使用“惰性”初始化。
- 在第一次使用后将文字保存在内存中对于这种简单的操作来说可能价格太高了
当前实施的优势
- 在一个地方定义的列表(与使用相同值对的 2 个不同地方的开关查找和手动列表填充相比)
- 重用代码进行查找和列表填充。
- 维护和编译时间检查的简单性。
关于更好的“漂亮代码”的任何想法?:)
理想情况下,我希望在定义列表时看到类似的内容,但在真正需要/使用之前不应初始化:
public static TLiteralDic FileStatus = new TLiteralDic () {
{TFiles.Status.Cancelled, Lists.FileStatus_Cancelled},
{TFiles.Status.Closed, Lists.FileStatus_Closed},
{TFiles.Status.OnHold, Lists.FileStatus_OnHold},
{TFiles.Status.Open, Lists.FileStatus_Open},
{TFiles.Status.Pending, Lists.FileStatus_Pending},
{TFiles.Status.Portal, Lists.FileStatus_Portal}
}