6

I'm using Dictionary<string, string> as configuration for instruments, and it'd be easier for my users who don't know a lot about programming to be able to get autocomplete from Visual Studio.

In Python I can make a Dictionary and access the different values with a dot operator.

d = {'name':'Joe', 'mood':'grumpy'}
d.name
d.mood

Does C# have a way to do this?

I realize all of the problems involved since dictionary is a just a generic collection (how generic? is it just a list of KeyValuePairs? interesting question). I'm not about to write a wrapper class for this to accomplish it (I'd like it to be a bit more flexible than using explicit properties with a custom class).

gunr2171
  • 16,104
  • 25
  • 61
  • 88
Oren Mazor
  • 4,437
  • 2
  • 29
  • 28

4 Answers4

7

You can already do that in C# with anonymous types:

var d = new { name = "Joe", mood = "grumpy"};
d.name
d.mood

Or real types:

var d = new Person { Name = "Joe", Mood = "grumpy"};
d.Name
d.Mood

And, in C# 4.0 we will have the DLR which will allow adding properties at runtime using the ExpandoObject:

dynamic d = new ExpandoObject();
d.name = "Joe";
d.mood = "grumpy";

However, I'm not sure that you can do IntelliSense using static analysis in C#.

The closest C# equivalent to what you have is

var d = new Dictionary<string, string>()
    { { "name", "Joe" }, { "mood", "grumpy" } };
d["name"]
d["mood"]

Which will not support IntelliSense.

If you are making an API, I would use real types.

workerbee
  • 57
  • 8
John Gietzen
  • 48,783
  • 32
  • 145
  • 190
  • `dynamic` won't let you add properties at run time by itself. `ExpandoObject` does all the magic, and you have to initialize that instead of an anonymous type. – Blindy Feb 08 '10 at 16:48
  • awesome. I didn't know about that. the whole api situation is a bit silly, but this is the easiest way I can keep people out of trouble, which is really what matters at the end of the day – Oren Mazor Feb 08 '10 at 17:12
  • Keep in mind that if you are relying on the users to create anonymous types, you will need to use reflection or the "dynamic" keyword to access the values. – John Gietzen Feb 08 '10 at 17:14
0

Seems like you want a struct. http://msdn.microsoft.com/en-us/library/0taef578.aspx

Edit: changed to a more up-to-date link.

Alison R.
  • 4,204
  • 28
  • 33
  • 1
    I rather like the idea of using a struct, provided you know what the fields/properties should be in advance. Which presumably you would if you're documenting it. – Powerlord Feb 08 '10 at 16:56
0

you are looking for imo method chaining.

Method chaining - why is it a good practice, or not?

a dictionary object is a collection (uses list) of key value pairs that also implements a hash table for access. It is almost n(1) in terms of its access speed.

public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
    ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 
    IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback

taken from

ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/fxref_mscorlib/html/589059d3-d7f8-e09b-705d-91a461971cc2.htm

In fact the retrieval algorithm changes as it gets larger as a hash table is less efficient for small numbers of items.

The linq approach would work also - no need to use anonymous types though

moodyPerson p = new moodyPerson{mood = "good", name="jim"};

however this does not force you to set all the properties of a moody person and will use its empty constructor.

you cant use intellisense if you want to access properties by strings. You would need to use reflection to implement this.

Community
  • 1
  • 1
John Nicholas
  • 4,778
  • 4
  • 31
  • 50
  • Looking at the source code for Dictionary https://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs,297 I cant see that the alg changes with the size – Magnus Jul 13 '20 at 09:34
  • well look somewhere else that answer is 10 years old. – John Nicholas Jan 05 '21 at 23:59
0

Don't get suckered into an elaborate solution with ExpandoObject() if you are planning to instantiate your objects at runtime (like from a database call), there is no intellisense for "dot notation"and it will produce a compile error if you try to use it. you can use ["propname"] bracket notation to access them however at this point you might as well have created custom class objects or just manipulate the values as needed in a DataTable()

J.Wolfe
  • 688
  • 8
  • 11