创建s到s 的常量(运行时永不更改)的最有效方法是什么?string
int
我试过使用const Dictionary,但是没有解决。
我可以用适当的语义实现一个不变的包装器,但这似乎并不完全正确。
对于那些提出要求的人,我正在生成的类中实现IDataErrorInfo,并正在寻找一种方法来使columnName查找进入我的描述符数组。
我不知道(测试时输入错误!d!哦!)该开关接受字符串,所以这就是我要使用的。谢谢!
创建s到s 的常量(运行时永不更改)的最有效方法是什么?string
int
我试过使用const Dictionary,但是没有解决。
我可以用适当的语义实现一个不变的包装器,但这似乎并不完全正确。
对于那些提出要求的人,我正在生成的类中实现IDataErrorInfo,并正在寻找一种方法来使columnName查找进入我的描述符数组。
我不知道(测试时输入错误!d!哦!)该开关接受字符串,所以这就是我要使用的。谢谢!
Answers:
用C#创建一个真正的编译时生成的常量字典并不是一件容易的事。实际上,这里没有任何答案能真正做到这一点。
有一种解决方案可以满足您的要求,尽管不一定是一种好的解决方案。请记住,根据C#规范,切换用例表被编译为常量哈希跳转表。也就是说,它们是常量字典,而不是一系列的if-else语句。因此,考虑这样的switch-case语句:
switch (myString)
{
case "cat": return 0;
case "dog": return 1;
case "elephant": return 3;
}
这正是您想要的。是的,我知道,这很丑陋。
当前框架中很少有不可变的集合。我可以想到.NET 3.5中一个相对轻松的选项:
用途Enumerable.ToLookup()
- Lookup<,>
该类是不可变的(但在rhs上是多值的);您可以Dictionary<,>
很容易地做到这一点:
Dictionary<string, int> ids = new Dictionary<string, int> {
{"abc",1}, {"def",2}, {"ghi",3}
};
ILookup<string, int> lookup = ids.ToLookup(x => x.Key, x => x.Value);
int i = lookup["def"].Single();
enum Constants
{
Abc = 1,
Def = 2,
Ghi = 3
}
...
int i = (int)Enum.Parse(typeof(Constants), "Def");
这是您最接近“ CONST词典”的内容:
public static int GetValueByName(string name)
{
switch (name)
{
case "bob": return 1;
case "billy": return 2;
default: return -1;
}
}
编译器将足够聪明,以使代码尽可能清晰。
如果使用4.5+ Framework,我将使用ReadOnlyDictionary(也用于列表的ReadOnly Collection)来执行只读映射/常量。它是通过以下方式实现的。
static class SomeClass
{
static readonly ReadOnlyDictionary<string,int> SOME_MAPPING
= new ReadOnlyDictionary<string,int>(
new Dictionary<string,int>()
{
{ "One", 1 },
{ "Two", 2 }
}
)
}
private static readonly Dictionary<string, string> _yourDictionaryName = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase) { { "One",1 }, { "Two",2 }, { "Three",3 }, };
这就是我的方法。
readonly Dictionary<TKey, TValue>
不等同于ReadOnlyDictionary<TKey, TValue>
。实际上,它们以“只读”方式彼此几乎是相反的。请参阅:dotnetfiddle.net/v0l4aA。
为什么不使用名称空间或类来嵌套您的值?它可能不完美,但是非常干净。
public static class ParentClass
{
// here is the "dictionary" class
public static class FooDictionary
{
public const string Key1 = "somevalue";
public const string Foobar = "fubar";
}
}
现在,您可以访问.ParentClass.FooDictionary.Key1等。
我不确定为什么没有人提到这个,但是在C#中由于无法分配const的原因,我使用了静态只读属性。
例:
public static readonly Dictionary<string, string[]> NewDictionary = new Dictionary<string, string[]>()
{
{ "Reference1", Array1 },
{ "Reference2", Array2 },
{ "Reference3", Array3 },
{ "Reference4", Array4 },
{ "Reference5", Array5 }
};
自从我绑定到winforms组合框后,这只是另一个想法:
public enum DateRange {
[Display(Name = "None")]
None = 0,
[Display(Name = "Today")]
Today = 1,
[Display(Name = "Tomorrow")]
Tomorrow = 2,
[Display(Name = "Yesterday")]
Yesterday = 3,
[Display(Name = "Last 7 Days")]
LastSeven = 4,
[Display(Name = "Custom")]
Custom = 99
};
int something = (int)DateRange.None;
为了从显示名称的int值从:
public static class EnumHelper<T>
{
public static T GetValueFromName(string name)
{
var type = typeof(T);
if (!type.IsEnum) throw new InvalidOperationException();
foreach (var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field,
typeof(DisplayAttribute)) as DisplayAttribute;
if (attribute != null)
{
if (attribute.Name == name)
{
return (T)field.GetValue(null);
}
}
else
{
if (field.Name == name)
return (T)field.GetValue(null);
}
}
throw new ArgumentOutOfRangeException("name");
}
}
用法:
var z = (int)EnumHelper<DateRange>.GetValueFromName("Last 7 Days");
为什么不:
public class MyClass
{
private Dictionary<string, int> _myCollection = new Dictionary<string, int>() { { "A", 1 }, { "B", 2 }, { "C", 3 } };
public IEnumerable<KeyValuePair<string,int>> MyCollection
{
get { return _myCollection.AsEnumerable<KeyValuePair<string, int>>(); }
}
}