我有一个便利类,它本质上是一个字典,它包含一个标记/值对列表,用于提交给API。
在最基本的层面上我所做的就是:
enum Tag
{
Name, Date, //There are many more
}
class RequestDictionary : Dictionary<Tag, string>
{
}
这很好地映射了API的需求,因为整个事物被发送并解析为字符串。然而,对于来电者来说并不是那么好;例如,调用者必须知道如何正确格式化Date
。
为了解决这个问题,我开始添加类型安全的特定于标签的属性。我将它们隔离在单独的界面中,这样它们就不会与正常的Dictionary属性混淆。
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); }
}
}
引入此界面后,调用者可以选择
dict[Tag.Date] = DateTime.Now.ToString(API_DATE_FORMAT);
或
dict.Tags.Date = DateTime.Now;
后者对调用者的工作量较少,特别是因为API_DATE_FORMAT实际上是私有的。
我希望调用者能够使用对象初始化器语法:
var dict = new RequestDictionary
{
Tags.Date = DateTime.Now
}
...但是这不会编译(错误是“无效的初始化成员声明符”)。
所以调用者似乎需要使用
var dict = new RequestDictionary
{
{ Tags.Date, DateTime.Now.ToString(API_DATE_FORMAT) }
};
......这显然不是很好的封装或方便。
当您要访问的属性是通过未包含在默认类接口中的接口公开时,是否有任何方法可以使用对象初始化程序语法初始化对象?
答案 0 :(得分:3)
以下代码可能符合您的需求:
var dict = new RequestDictionary
{
Tags = { Date = DateTime.Now }
};
关键是使用Tags = { Date
(即一次降低一级)而不是Tags.Date =
。
我承认代码看起来像它不会起作用,因为看起来像你正在分配给只读属性(即{{1 }})。但它确实有效(由于object initializers work)。