Создание сгенерированного постоянного словаря действительно времени компиляции в C# не является действительно простой задачей. На самом деле ни один из ответов здесь действительно не достигает этого.
существует одно решение хотя, который отвечает Вашим требованиям, хотя не обязательно хорошее; помните, что согласно спецификации C#, таблицы случая переключателя составлены к постоянным таблицам переходов хеша. Таким образом, они - постоянные словари, не серия если еще операторы. Поэтому рассмотрите оператора case оператора switch как это:
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");
Это - самая близкая вещь, которую можно получить к "Словарю КОНСТАНТЫ":
public static int GetValueByName(string name)
{
switch (name)
{
case "bob": return 1;
case "billy": return 2;
default: return -1;
}
}
компилятор будет достаточно умен для создания кода, максимально чистого.
Кажется, нет никакого стандартного неизменного интерфейса для словарей, так создание обертки походит на единственную разумную опцию, к сожалению.
Редактирование : Marc Gravell нашел ILookup, который я пропустил - который позволит Вам, по крайней мере, стараться не создавать новую обертку, хотя все еще необходимо преобразовать Словарь с.ToLookup ().
, Если это - потребность, ограниченная к определенному сценарию, Вы могли бы быть более обеспечены с более ориентированным на бизнес-логику интерфейсом:
interface IActiveUserCountProvider
{
int GetMaxForServer(string serverName);
}
Просто другая идея, так как я связываю с полем комбинированного списка 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;
Для получения международного значения от отображаемого имени от :
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>>(); }
}
}