English 中文(简体)
C# 在实施接口时的相互关系和避孕
原标题:C# Covariance and Contravariance when implementing interfaces

我最近决定恢复我对C#基本原理的记忆,这样可能是三边的,但我会 following入以下问题:

StringCollection was used in .NET v1.0 in order to create a strongly typed collection for strings as opposed to an object based ArrayList (this was later enhanced by including Generic collections):

快速浏览Stlection下的定义,请参看:

// 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) 

Any ideas what causes this?

感谢!

最佳回答

The behavior is caused by the explicit implementation of IList.Add(object) rather than co/contravariance. Per the MSDN documentation, StringCollection explicitly implements IList.Add(object); the Add(string) method is unrelated. The implementation may resemble something like this:

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)
    }
}

This distinction can be observed:

  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

The above doesn t address why this pattern is implemented. The C# language specification states that [§13.4.1, emphasis added]:

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. [...]

www.un.org/Depts/DGACM/index_spanish.htm 不可能通过在职业、财产存取或索引领取方面完全合格的名称获得明确的接口成员执行。 只有通过一个接口,才能获得一个明确的接口成员执行,在这种情况下,仅以其成员名称提及。

斯特林戈坚持要求的国际语言行为——国际语言学会不保证任何任意的物体都可以加入。 强力竞争提供了更有力的保障——主要是它只包含扼杀。 该类别包括自己的强型方法:Add,Contains,Item,以及作为检索的标准使用情形中的其他方法: IList 。 但是,如果试图增加一个并非扼杀性的项目,它仍然完全运作并运行,接受和返还物体,但退回错误代码(作为IList许可)。

归根结蒂,该类的接口(即明确实施)是否由该类作者自行决定。 就框架类别而言,明确分类列入MSDN文件,但不能作为班级成员查阅(例如,在汽车校正环境下)。

问题回答

如果你使用2.0+网,我只使用一般用途:

IList<string> list = new List<string>();

这应当给你一切希望。

IList.Add(object)可以接受除扼杀以外的参数——它可以接受任何类型的参数。 因此,如果你宣布将接口付诸实施,只接受插图,则不再与接口规格相匹配,因为现在我无法在<条码>上通过,例如

Variance can work the other way: if the interface method was declared to accept strings, then accepting objects would be alright, since strings are also objects, and therefore any input to the interface s method would also be acceptable input to your implementation. (However, you would still have to provide an explicit interface implementation with a method accepting string, because in C# an interface method implementation much exactly match the interface method declaration.)

, 基本规定是:你可以打电话到。 添加,并从盒式<条码>上通过任何物体作为参数。 Int to another IList to a System.DivideByZeroException. 如果你只提供<代码>Add(string )方法,你就没有达到这一要求,因为你只能补充说明。

换言之,你无法打电话<条码>。 增加(新的目标);,如果接口得到适当实施,则应当完全可行。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签