What is the most efficient way to create a constant (never changes at runtime) mapping of strings to ints?
I've tried using a const Dictionary, but that didn't work out.
I could implement a immutable wrapper with appropriate semantics, but that still doesn't seem totally right.
For those who have asked, I'm implementing IDataErrorInfo in a generated class and am looking for a way to make the columnName lookup into my array of descriptors.
I wasn't aware (typo when testing! d'oh!) that switch accepts strings, so that's what I'm gonna use. Thanks!
-
There does not seem to be any standard immutable interface for dictionaries, so creating a wrapper seems like the only reasonable option, unfortunately.
Edit: Marc Gravell found the ILookup that I missed - that will allow you to at least avoid creating a new wrapper, although you still need to transform the Dictionary with .ToLookup().
If this is a need constrained to a specific scenario, you might be better off with a more business-logic-oriented interface:
interface IActiveUserCountProvider { int GetMaxForServer(string serverName); } -
There are precious few immutable collections in the current framework. I can think of one relatively pain-free option in .NET 3.5:
Use
Enumerable.ToLookup()- theLookup<,>class is immutable (but multi-valued on the rhs); you can do this from aDictionary<,>quite easily: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(); -
What's about
public static readonly?Sander : This would make the Dictionary **reference** read-only, not the contents themselves.Tamir : Actually, I was failed to find real scenario for mapping strings to ints, except messagebag. However, if it's about Pyton-based programming, I'll vote for using enum constant instead of all those :) -
enum Constants { Abc = 1, Def = 2, Ghi = 3 } ... int i = (int)Enum.Parse(typeof(Constants), "Def");David Schmitt : Interesting idea! I'm wondering how good the Parse() call performs. I fear only a profiler can answer that one. -
Creating a truly compile-time generated constant dictionary in C# is not really a straightforward task. Actually, none of the answers here really achieve that.
There is one solution though which meets your requirements, although not necessarily a nice one; remember that according to the C# specification, switch-case tables are compiled to constant hash jump tables. That is, they are constant dictionaries, not a series of if-else statements. So consider a switch-case statement like this:
switch (myString) { case "cat": return 0; case "dog": return 1; case "elephant": return 3; }This is exactly what you want. And yes, I know, it's ugly.
mackenir : Hey, I just learned something.David Schmitt : It's generated code anyways, has good performance characteristics, can be compile-time computed, and has other nice properties for my use case too. I'll be doing it like this!Tom Anderson : just be careful that returning non-value types, even like this, will break your classes immutability. -
This is the closest thing you can get to a "CONST Dictionary":
public static int GetValueByName(string name) { switch (name) { case "bob": return 1; case "billy": return 2; default: return -1; } }The compiler will be smart enough to build the code as clean as possible.
-
what if we want to populate the dictionary from database?
David Schmitt : Good question! Populating the dict at run-time doesn't allow the dict to be compile-time optimized like the switch() statement. I'd go for a ToDictionary() or ToLookup() Linq call there. See e.g. http://msdn.microsoft.com/en-us/library/system.linq.enumerable.tolookup.aspx -
Why not:
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>>(); } } }David Schmitt : Because this is quite expensive compared to the available alternatives under the specified conditions.
0 comments:
Post a Comment