假设我有一个函数需要对UsefulType
的实例进行操作,但必须接受类型为string
的参数。为此,我可以在函数中查找一些string -> OtherType
映射。我可以制作一个看起来像的界面
public interface IMapper {
public UsefulType this[string key];
public bool ContainsKey(string key);
}
并给我的方法签名
public Task DoSomething(string thing, IMapper lookup)
我很清楚,IDictionary<string, UsefulType>
在逻辑上实现了IMapper
,但规范定义在其继承树中当然不包括IMapper
。C#是否提供了任何功能,使得用户可以将Dictionary
直接传递到该函数中,而不必担心实现自己的IMapper
?
(事实上,DoSomething
的签名只包含一个字符串-这是约束-而IMapper
将由DoSomething
的类型所有。但我仍然需要用户提供一个IMapper
用于类型实例化,例如(
否,除非您能够更改现有类型的源代码并重新编译它们,否则您不能追溯性地使现有类型实现/继承其他类型。
请考虑接受IReadOnlyDictionary
。它和你的IMapper
没什么不同。它不应该有太多需要实现。如果映射是有限的,那么Count
应该是微不足道的。Keys
和Values
都返回IEnumerable
s,因此,如果不方便返回集合,则可以使用yield return
编写迭代器。您也可以在GetEnumerator
中编写迭代器(无需实现您自己的IEnumerator
(,因此IMO,对于有限映射来说,这并不是更多的工作。你现在可能不需要这些额外的属性,但谁知道呢,你以后可能需要它们!
如果映射有无限多的元素,那么Count
就没有意义了。在这种情况下,您可以编写IMapper
:的字典实现
public class DictionaryMapper : IMapper
{
private IReadOnlyDictionary<string, UsefulType> dict;
public DictionaryMapper(IReadOnlyDictionary<string, UsefulType> dict)
{
this.dict = dict;
}
public UsefulType this[string key] => dict[key];
public bool ContainsKey(string key) => dict.ContainsKey(key);
}
现在给定一个字典d
,您只需执行new DictionaryMapper(d)
即可从中获得IMapper
实现。