Background
I have a convenience class which is essentially a dictionary that holds a tag/value pair list for submission to an API.
At its very basic level all I did is this:
enum Tag
{
Name, Date, //There are many more
}
class RequestDictionary : Dictionary<Tag, string>
{
}
This maps well to the needs of the API, since the whole thing gets sent and parsed as a string. However, it's not so great for the caller; for example, the caller has to know how to format the Date
properly.
To address this, I started adding tag-specific properties that are type safe. I have them sequestered in separate interface so they don't get confused with the normal Dictionary properties.
enum Tag
{
Name, Date
}
interface ITags
{
string Name { get; set; }
DateTime Date { get; set; }
}
class RequestDictionary : Dictionary<Tag, string>, ITags
{
public ITags Tags { get { return this; } }
string ITags.Name
{
get { return this[Tag.Name]; }
set { this[Tag.Name] = value; }
}
DateTime ITags.Date
{
get { return DateTime.ParseExact(this[Tag.Date], API_DATE_FORMAT, CultureInfo.InvariantCulture); }
set { this[Tag.Name] = value.ToString(API_DATE_FORMAT); }
}
}
After introducing this interface, the caller has a choice of
dict[Tag.Date] = DateTime.Now.ToString(API_DATE_FORMAT);
or
dict.Tags.Date = DateTime.Now;
The latter is less work for the caller, especially since API_DATE_FORMAT is actually private.
The issue
I want the caller to be able to use object initializer syntax:
var dict = new RequestDictionary
{
Tags.Date = DateTime.Now
}
...but this does not compile (the error is "Invalid initializer member declarator").
So it seems that the caller will need to use
var dict = new RequestDictionary
{
{ Tags.Date, DateTime.Now.ToString(API_DATE_FORMAT) }
};
...which is obviously not as well encapsulated or convenient.
Is there any way to initialize an object using object initializer syntax when the property you wish to access is exposed via an interface that is not included in the default class interface?