简体   繁体   English

我可以定义一个 IDictionary 在 C# 中实现的接口吗?

[英]Can I define an Interface that IDictionary implements in C#?

Say I have a function that needs to operate on a instance of UsefulType , but must take an argument of type string .假设我有一个函数需要对UsefulType的实例进行UsefulType ,但必须采用string类型的参数。 To do so, within the function I might look up some string -> OtherType mapping.为此,我可能会在函数中查找一些string -> OtherType映射。 I could make an interface that looks like我可以制作一个看起来像的界面

public interface IMapper {
    public UsefulType this[string key];
    public bool ContainsKey(string key);
}

and give my method the signature并给我的方法签名

public Task DoSomething(string thing, IMapper lookup)

It is clear to me that an IDictionary<string, UsefulType> logically implements IMapper , but of course the canonical definition doesn't include IMapper in its inheritance tree.我很清楚IDictionary<string, UsefulType>逻辑上实现了IMapper ,但当然规范定义在其继承树中不包括IMapper Does C# provide any functionality such that a user could pass a Dictionary directly into this function without having to worry about implementing their own IMapper ? C# 是否提供任何功能,以便用户可以将Dictionary直接传递给此函数,而不必担心实现自己的IMapper

(In reality the signature for DoSomething would just contain a string - that's the constraint - and the IMapper would be owned by DoSomething 's type. But I would still need the user to provide an IMapper for type instantiation, for example) (实际上, DoSomething的签名将只包含一个字符串——这是约束——并且IMapper将由DoSomething的类型拥有。但我仍然需要用户提供一个IMapper用于类型实例化,例如)

No, you cannot retroactively make existing types implement/inherit other types, unless you are able to change their source code and recompile them.不,您不能追溯地使现有类型实现/继承其他类型,除非您能够更改它们的源代码并重新编译它们。

Consider accepting an IReadOnlyDictionary instead.考虑接受IReadOnlyDictionary代替。 It isn't that different from your IMapper .它与您的IMapper没有什么不同。 It shouldn't be a lot more to implement.实施起来不应该太多 Count should be trivial if your mapping is finite.如果您的映射是有限的, Count应该是微不足道的。 Keys and Values all return IEnumerable s, so that gives you the ability to write iterators with yield return if it's inconvenient to return a collection. KeysValues都返回IEnumerable s,因此如果返回集合不方便,您可以编写带有yield return迭代器。 You can also write iterators in GetEnumerator (no need to implement your own IEnumerator ), so IMO, it's not that much more work for finite mappings.您还可以在GetEnumerator编写迭代器(无需实现您自己的IEnumerator ),因此 IMO,对于有限映射而言,它并没有那么多工作。 You might not need these extra properties right now, but who knows, you might need them later!您现在可能不需要这些额外的属性,但谁知道呢,您以后可能需要它们!

If your mapping has infinitely many elements, then Count doesn't quite make sense.如果您的映射有无限多个元素,那么Count就没有什么意义了。 In that case, you can write a dictionary implementation of IMapper :在这种情况下,您可以编写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);
}

Now given a dictionary d , you can just do new DictionaryMapper(d) to get a IMapper implementation from that.现在给定一个字典d ,您只需执行new DictionaryMapper(d)即可从中获取IMapper实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM