将对象初始化程序语法与接口一起使用

Joh*_* Wu 5 .net c# interface

背景

我有一个便利类,它本质上是一个字典,它包含一个标记/值对列表,用于提交给API.

在最基本的层面上,我所做的就是:

enum Tag
{
    Name, Date, //There are many more
}

class RequestDictionary : Dictionary<Tag, string>
{
}
Run Code Online (Sandbox Code Playgroud)

这很好地映射了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); }
    }
}
Run Code Online (Sandbox Code Playgroud)

引入此接口后,调用者可以选择

dict[Tag.Date] = DateTime.Now.ToString(API_DATE_FORMAT);
Run Code Online (Sandbox Code Playgroud)

要么

dict.Tags.Date = DateTime.Now;
Run Code Online (Sandbox Code Playgroud)

后者对调用者的工作量较少,特别是因为API_DATE_FORMAT实际上是私有的.

问题

我希望调用者能够使用对象初始化器语法:

var dict = new RequestDictionary
{
    Tags.Date = DateTime.Now
}
Run Code Online (Sandbox Code Playgroud)

...但是这不会编译(错误是"无效的初始化成员声明符").

所以似乎调用者需要使用

var dict = new RequestDictionary
{
    { Tags.Date, DateTime.Now.ToString(API_DATE_FORMAT) }    
};
Run Code Online (Sandbox Code Playgroud)

......这显然不是封装或方便的.

当您希望访问的属性是通过默认类接口中未包含的接口公开时,是否有任何方法可以使用对象初始化程序语法初始化对象?

mjw*_*lls 3

以下代码可能会满足您的需求:

var dict = new RequestDictionary
{
    Tags = { Date = DateTime.Now }
};
Run Code Online (Sandbox Code Playgroud)

关键是使用Tags = { Date(即一次下降一级)而不是Tags.Date =.

我承认该代码看起来不起作用,因为它看起来像是您正在分配给只读属性(即Tags)。但它确实有效(由于对象初始值设定项的工作方式)。