20.2 Interface members

The members of an interface are the members inherited from the base
interfaces and the members declared by the
interface itself.
interface-member-declarations:
interface-member-declaration
interface-member-declarations interface-member-declaration
interface-member-declaration:
interface-method-declaration
interface-property-declaration
interface-event-declaration
interface-indexer-declaration
An interface declaration may declare zero or more members. The members of
an interface must be methods,
properties, events, or indexers. An interface cannot contain constants,
fields, operators, instance constructors,
destructors, or types, nor can an interface contain static members of any
kind.
All interface members implicitly have public access. It is a compile-time
error for interface member declarations
to include any modifiers. In particular, interface members cannot be
declared with the modifiers abstract,
public, protected, internal, private, virtual, override, or static.
[Example: The example
public delegate void StringListEvent(IStringList sender);
public interface IStringList
{
void Add(string s);
int Count { get; }
event StringListEvent Changed;
Chapter 20 Interfaces
281
string this[int index] { get; set; }
}
declares an interface that contains one each of the possible kinds of
members: A method, a property, an event,
and an indexer. end example]
An interface-declaration creates a new declaration space (§10.3), and the
interface-member-declarations
immediately contained by the interface-declaration introduce new members
into this declaration space. The
following rules apply to interface-member-declarations:
? The name of a method must differ from the names of all properties and
events declared in the same interface.
In addition, the signature (§10.6) of a method must differ from the
signatures of all other methods declared in
the same interface, and two methods declared in the same interface may not
have signatures that differ solely
by ref and out.
? The name of a property or event must differ from the names of all other
members declared in the same
interface.
? The signature of an indexer must differ from the signatures of all other
indexers declared in the same
interface.
The inherited members of an interface are specifically not part of the
declaration space of the interface. Thus, an
interface is allowed to declare a member with the same name or signature as
an inherited member. When this
occurs, the derived interface member is said to hide the base interface
member. Hiding an inherited member is
not considered an error, but it does cause the compiler to issue a warning.
To suppress the warning, the
declaration of the derived interface member must include a new modifier to
indicate that the derived member is
intended to hide the base member. This topic is discussed further in §10.7.1
.2.
If a new modifier is included in a declaration that doesn?t hide an
inherited member, a warning is issued to that
effect. This warning is suppressed by removing the new modifier.
[Note: The members in class object are not, strictly speaking, members of
any interface (§20.2). However, the
members in class object are available via member lookup in any interface
type (§14.3). end note]
20.2.1 Interface methods
Interface methods are declared using interface-method-declarations:
interface-method-declaration:
attributesopt newopt return-type identifier ( formal-parameter-listopt ) ;
The attributes, return-type, identifier, and formal-parameter-list of an
interface method declaration have the same
meaning as those of a method declaration in a class (§17.5). An interface
method declaration is not permitted to


specify a method body, and the declaration therefore always ends with a
semicolon.
20.2.2 Interface properties
Interface properties are declared using interface-property-declarations:
interface-property-declaration:
attributesopt newopt type identifier { interface-accessors }
interface-accessors:
attributesopt get ;
attributesopt set ;
attributesopt get ; attributesopt set ;
attributesopt set ; attributesopt get ;
The attributes, type, and identifier of an interface property declaration
have the same meaning as those of a
property declaration in a class (§17.6).
The accessors of an interface property declaration correspond to the
accessors of a class property declaration
(§17.6.2), except that the accessor body must always be a semicolon. Thus,
the accessors simply indicate whether
the property is read-write, read-only, or write-only.
C# LANGUAGE SPECIFICATION
282
20.2.3 Interface events
Interface events are declared using interface-event-declarations:
interface-event-declaration:
attributesopt newopt event type identifier ;
The attributes, type, and identifier of an interface event declaration have
the same meaning as those of an event
declaration in a class (§17.7).
20.2.4 Interface indexers
Interface indexers are declared using interface-indexer-declarations:
interface-indexer-declaration:
attributesopt newopt type this [ formal-parameter-list ] {
interface-accessors }
The attributes, type, and formal-parameter-list of an interface indexer
declaration have the same meaning as
those of an indexer declaration in a class (§17.8).
The accessors of an interface indexer declaration correspond to the
accessors of a class indexer declaration
(§17.8), except that the accessor body must always be a semicolon. Thus,
the accessors simply indicate whether
the indexer is read-write, read-only, or write-only.
20.2.5 Interface member access
Interface members are accessed through member access (§14.5.4) and indexer
access (§14.5.6.2) expressions of
the form I.M and I[A], where I is an expression having an interface type, M
is a method, property, or event of
that interface type, and A is an indexer argument list.
For interfaces that are strictly single-inheritance (each interface in the
inheritance chain has exactly zero or one
direct base interface), the effects of the member lookup (§14.3), method
invocation (§14.5.5.1), and indexer
access (§14.5.6.2) rules are exactly the same as for classes and structs:
More derived members hide less derived
members with the same name or signature. However, for multiple-inheritance
interfaces, ambiguities can occur
when two or more unrelated base interfaces declare members with the same
name or signature. This section
shows several examples of such situations. In all cases, explicit casts can
be used to resolve the ambiguities.
[Example: In the example
interface IList
{
int Count { get; set; }
}
interface ICounter
{
void Count(int i);
}
interface IListCounter: IList, ICounter {}
class C
{
void Test(IListCounter x) {
x.Count(1); // Error
x.Count = 1; // Error
((IList)x).Count = 1; // Ok, invokes IList.Count.set
((ICounter)x).Count(1); // Ok, invokes ICounter.Count
}
}
the first two statements cause compile-time errors because the member
lookup (§14.3) of Count in
IListCounter is ambiguous. As illustrated by the example, the ambiguity is
resolved by casting x to the
appropriate base interface type. Such casts have no run-time costs?they
merely consist of viewing the instance
as a less derived type at compile-time. end example]
[Example: In the example
Chapter 20 Interfaces
283
interface IInteger
{
void Add(int i);
}
interface IDouble
{
void Add(double d);
}
interface INumber: IInteger, IDouble {}
class C
{
void Test(INumber n) {


n.Add(1); // Error, both Add methods are applicable
n.Add(1.0); // Ok, only IDouble.Add is applicable
((IInteger)n).Add(1); // Ok, only IInteger.Add is a candidate
((IDouble)n).Add(1); // Ok, only IDouble.Add is a candidate
}
}
the invocation n.Add(1) is ambiguous because a method invocation (§14.5.5.1)
requires all overloaded
candidate methods to be declared in the same type. However, the invocation
n.Add(1.0) is permitted because
only IDouble.Add is applicable. When explicit casts are inserted, there is
only one candidate method, and thus
no ambiguity. end example]
[Example: In the example
interface IBase
{
void F(int i);
}
interface ILeft: IBase
{
new void F(int i);
}
interface IRight: IBase
{
void G();
}
interface IDerived: ILeft, IRight {}
class A
{
void Test(IDerived d) {
d.F(1); // Invokes ILeft.F
((IBase)d).F(1); // Invokes IBase.F
((ILeft)d).F(1); // Invokes ILeft.F
((IRight)d).F(1); // Invokes IBase.F
}
}
the IBase.F member is hidden by the ILeft.F member. The invocation d.F(1)
thus selects ILeft.F, even
though IBase.F appears to not be hidden in the access path that leads
through IRight.
The intuitive rule for hiding in multiple-inheritance interfaces is simply
this: If a member is hidden in any access
path, it is hidden in all access paths. Because the access path from
IDerived to ILeft to IBase hides
IBase.F, the member is also hidden in the access path from IDerived to
IRight to IBase. end example]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SmartGit 20.2是一款强大的分布式版本控制工具,旨在提供简洁易用的用户界面和丰富的版本控制功能。以下是它的一些特点和优势: 1. 简洁易用的用户界面:SmartGit 20.2拥有直观的用户界面,使得版本控制操作更加简单和容易上手。它提供了直观的图形化显示,使用户能够轻松地进行代码的提交、拉取、合并等操作。 2. 支持多种版本控制系统:SmartGit 20.2支持多种版本控制系统,包括Git、Mercurial和Subversion等,允许用户在同一个工具中管理多个项目,无需切换不同的版本控制工具。 3. 强大的分支管理:SmartGit 20.2提供了强大的分支管理功能,使用户能够轻松地创建、切换、合并和删除分支,同时能够清晰地查看分支之间的差异和历史记录。 4. 智能的代码提交:SmartGit 20.2提供了智能的代码提交功能,可以自动检测并提交相关的修改内容,减少手动添加文件的繁琐操作。 5. 高级的比较和合并工具:SmartGit 20.2内置了高级的比较和合并工具,可以对代码进行精确的差异比较和冲突解决,使得团队协作更加高效。 6. 高度可定制化:SmartGit 20.2允许用户根据自己的需求进行高度的定制化设置,在用户界面、快捷键、外观等方面提供了丰富的选项。 总之,SmartGit 20.2是一款功能强大、易于使用的版本控制工具,适用于各种大小的项目和团队。它的直观界面和丰富的功能使得代码的管理和协作更加简便和高效。无论是个人开发者还是团队,SmartGit 20.2都是一个值得推荐的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值