- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我最近决定复习一下 C# 基础知识,所以这可能是微不足道的,但我遇到了以下问题:
StringCollection
在 .NET v1.0 中用于为字符串创建强类型集合,而不是基于 ArrayList
的对象
(这后来通过包含通用集合得到增强):
快速浏览一下 StringCollection
定义,您可以看到以下内容:
// Summary:
// Represents a collection of strings.
[Serializable]
public class StringCollection : IList, ICollection, IEnumerable
{
...
public int Add(string value);
...
}
您可以看到它实现了 IList
,其中包含以下声明(以及其他一些声明):
int Add(object value);
但不是:
int Add(string value);
我的第一个假设是,由于 .NET 框架协变规则,这是可能的。
所以为了确保,我尝试编写自己的类来实现 IList
并进行更改
int Add(object value);
检索字符串类型而不是对象类型,但令我惊讶的是,在尝试编译项目时,我遇到了编译时错误:
does not implement interface member 'System.Collections.IList.Add(object)'
知道是什么原因造成的吗?
谢谢!
最佳答案
该行为是由 IList.Add(object)
的显式实现引起的,而不是由协变/逆变引起的。根据 MSDN 文档,StringCollection 显式实现了 IList.Add(object)
; Add(string)
方法无关。实现可能类似于这样:
class StringCollection : IList
{
...
public int Add(string value)
{} // implementation
public int IList.Add (object value)
{
if (!value is string)) return -1;
return Add(value as string)
}
}
可以观察到这种区别:
StringCollection collection = new StringCollection();
collection.Add(1); // compile error
(collection as IList).Add(1); // compiles, runtime error
(collection as IList).Add((object)"") // calls interface method, which adds string to collection
附录
以上内容并未说明实现此模式的原因。 C# 语言规范指出 [§13.4.1,已强调]:
In some cases, the name of an interface member may not be appropriate for the implementing class, in which case the interface member may be implemented using explicit interface member implementation. [...]
It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation, property access, or indexer access. An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.
StringCollection 遵循所需的 IList 行为——IList 不保证可以向其中添加任何任意对象。 StringCollection 提供了更强的保证——主要是它只包含字符串。该类包括它自己的强类型方法,用于 Add
、Contains
、Item
以及其他用于标准用例的方法,其中它作为StringCollection
而不是 IList
。但它仍然可以作为 IList
完美运行,接受和返回对象,但如果尝试添加不是字符串的项目,则返回错误代码(如 IList 允许的那样)。
最终,接口(interface)是否出现在类中(即显式实现)由类作者自行决定。对于框架类,显式实现包含在 MSDN 文档中,但不能作为类成员访问(例如,显示在自动完成上下文中)。
关于C#实现接口(interface)时的协变和逆变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7054497/
我正在尝试在我的代码库中为我正在编写的游戏服务器更多地使用接口(interface),并了解高级概念以及何时应该使用接口(interface)(我认为)。在我的例子中,我使用它们将我的包相互分离,并使
我有一个名为 Widget 的接口(interface),它在我的整个项目中都在使用。但是,它也用作名为 Widget 的组件的 Prop 。 处理此问题的最佳方法是什么?我应该更改我的 Widget
有一个接口(interface)可以是多个接口(interface)之一 interface a {x:string} interface b {y:string} interface c {z:st
我遇到了一种情况,我需要调用第三方服务来获取一些信息。这些服务对于不同的客户可能会有所不同。我的界面中有一个身份验证功能,如下所示。 interface IServiceProvider { bool
在我的例子中,“RequestHandlerProxy”是一个结构,其字段为接口(interface)“IAdapter”,接口(interface)有可能被调用的方法,该方法的输入为结构“Reque
我有一个接口(interface)Interface1,它已由类A实现,并且设置了一些私有(private)变量值,并且我将类A的对象发送到下一个接受输入作为Interface2的类。那么我怎样才能将
假设我有这样的类和接口(interface)结构: interface IService {} interface IEmailService : IService { Task SendAs
有人知道我在哪里可以找到 XML-RPC 接口(interface)的定义(在 OpenERP 7 中)?我想知道创建或获取对象需要哪些参数和对象属性。每个元素的 XML 示例也将非常有帮助。 最佳答
最近,我一直在阅读有关接口(interface)是抽象的错误概念的文章。一篇这样的帖子是http://blog.ploeh.dk/2010/12/02/InterfacesAreNotAbstract
如果我有一个由第三方实现的现有 IInterface 后代,并且我想添加辅助例程,Delphi 是否提供了任何简单的方法来实现此目的,而无需手动重定向每个接口(interface)方法?也就是说,给定
我正在尝试将 Article 数组分配给我的 Mongoose 文档,但 Typescript 似乎不喜欢这样,我不知道为什么它显示此警告/错误,表明它不可分配. 我的 Mongoose 模式和接口(
我有两个接口(interface): public interface IController { void doSomething(IEntity thing); } public inte
是否可以创建一个扩展 Serializable 接口(interface)的接口(interface)? 如果是,那么扩展接口(interface)的行为是否会像 Serilizable 接口(int
我试图在两个存储之间创建一个中间层,它从存储 A 中获取数据,将其转换为相应类型的存储 B,然后存储它。由于我需要转换大约 50-100 种类型,我希望使用 map[string]func 并根据 s
我正在处理一个要求,其中我收到一个 JSON 对象,其中包含一个日期值作为字符串。我的任务是将 Date 对象存储在数据库中。 这种东西: {"start_date": "2019-05-29", "
我们的方法的目标是为我们现有的 DAO 和模型类引入接口(interface)。模型类由各种类型的资源 ID 标识,资源 ID 不仅仅是随机数,还带有语义和行为。因此,我们必须用对象而不是原始类型来表
Collection 接口(interface)有多个方法。 List 接口(interface)扩展了 Collection 接口(interface)。它声明与 Collection 接口(int
我有一个 Java 服务器应用程序,它使用 Jackson 使用反射 API 对 DTO 进行一般序列化。例如对于这个 DTO 接口(interface): package com.acme.libr
如果我在 Kotlin 中有一个接口(interface): interface KotlinInterface { val id: String } 我可以这样实现: class MyCla
我知道Java中所有访问修饰符之间的区别。然而,有人问了我一个非常有趣的问题,我很难找到答案:Java 中的 private 接口(interface)和 public 接口(interface)有什
我是一名优秀的程序员,十分优秀!