📄 20.2.5.htm
字号:
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Hyperlinked ECMA C# Language Specification</title><meta name="author" content="Jon Jagger" /><link rel="stylesheet" href="ecma334.css"></link></head><body><div align="right"><em><a href="http://www.jaggersoft.com">Jon Jagger</a></em></div><div align="right"><a href="mailto:jon@jaggersoft.com">jon@jaggersoft.com</a></div><form method="get" action="http://search.atomz.com/search/"><input size="30" name="sp-q"></input><input type="submit" value="Search C# Spec"></input><input type="hidden" name="sp-a" value="sp10024177"></input><input type="hidden" name="sp-f" value="ISO-8859-1"></input></form><a href="toc.htm">Table of Contents</a> <a href="1.htm">1</a> <a href="2.htm">2</a> <a href="3.htm">3</a> <a href="4.htm">4</a> <a href="5.htm">5</a> <a href="6.htm">6</a> <a href="7.htm">7</a> <a href="8.htm">8</a> <a href="9.htm">9</a> <a href="10.htm">10</a> <a href="11.htm">11</a> <a href="12.htm">12</a> <a href="13.htm">13</a> <a href="14.htm">14</a> <a href="15.htm">15</a> <a href="16.htm">16</a> <a href="17.htm">17</a> <a href="18.htm">18</a> <a href="19.htm">19</a> <a href="20.htm">20</a> <a href="21.htm">21</a> <a href="22.htm">22</a> <a href="23.htm">23</a> <a href="24.htm">24</a> <a href="25.htm">25</a> <a href="notes.htm">Notes</a> <a href="HyperlinkedCSharpECMA.zip">Download</a><span class="ruler"></span><span class="heading">ECMA-334 C# Language Specification</span><span class="navigate"><a href="20.2.4.htm"><img src="previous.gif" alt="previous" border="0" /></a><a href="20.3.htm"><img src="next.gif" alt="next" border="0" /></a></span><span class="clause-depth"><a href="19.htm"><img src="previous.gif" alt="previous at this level" border="0" /></a><a href="21.htm"><img src="next.gif" alt="next at this level" border="0" /></a> <span class="clause-number-link"><a href="20.htm">20</a></span><span class="clause-title-previous"> Interfaces</span></span><span class="clause-depth"><a href="20.1.htm"><img src="previous.gif" alt="previous at this level" border="0" /></a><a href="20.3.htm"><img src="next.gif" alt="next at this level" border="0" /></a> <span class="clause-number-link"><a href="20.2.htm">20.2</a></span><span class="clause-title-previous"> Interface members</span></span><span class="clause-depth"><a href="20.2.4.htm"><img src="previous.gif" alt="previous at this level" border="0" /></a><a href="20.2.5.htm"><img src="next.gif" alt="next at this level" border="0" /></a> <span class="clause-number">20.2.5</span><span class="clause-title"> Interface member access</span></span><span class="locator">
Paragraph 1</span><span class="paragraph"><span class="sentence"><span class="sentence-number">1</span> <a name="P1S1"></a>Interface members are accessed through member access (<a href="14.5.4.htm">§14.5.4</a>) and indexer access (<a href="14.5.6.2.htm">§14.5.6.2</a>) expressions of the form I.M and I[A], where I is an instance of an interface type, M is a method, property, or event of that interface type, and A is an indexer argument list.</span> </span><span class="locator">
Paragraph 2</span><span class="paragraph"><span class="sentence"><span class="sentence-number">1</span> <a name="P2S1"></a>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 (<a href="14.3.htm">§14.3</a>), method invocation (<a href="14.5.5.1.htm">§14.5.5.1</a>), and indexer access (<a href="14.5.6.2.htm">§14.5.6.2</a>) rules are exactly the same as for classes and structs: More derived members hide less derived members with the same name or signature.</span> <span class="sentence"><span class="sentence-number">2</span> <a name="P2S2"></a>However, for multiple-inheritance interfaces, ambiguities can occur when two or more unrelated base interfaces declare members with the same name or signature.</span> <span class="sentence"><span class="sentence-number">3</span> <a name="P2S3"></a>This section shows several examples of such situations.</span> <span class="sentence"><span class="sentence-number">4</span> <a name="P2S4"></a>In all cases, explicit casts can be used to resolve the ambiguities.</span> </span><span class="paragraph"><span class="example">[Example: In the example <pre class="code-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
}
}
</pre>the first two statements cause compile-time errors because the member lookup (<a href="14.3.htm">§14.3</a>) 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]</span> </span><span class="paragraph"><span class="example">[Example: In the example <pre class="code-example">
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
}
}
</pre>the invocation n.Add(1) is ambiguous because a method invocation (<a href="14.5.5.1.htm">§14.5.5.1</a>) 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]</span> </span><span class="paragraph"><span class="example">[Example: In the example <pre class="code-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
}
}
</pre>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. </span></span><span class="paragraph"><span class="example">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]</span> </span><span class="ruler"></span><table><tr><td><table align="left" bgcolor="navy"><tr bgcolor="navy"><td><font face="Arial,sans-serif" size="6" color="yellow"><strong>{ JSL }</strong></font></td></tr></table></td></tr><tr><td><font face="Arial,sans-serif" size="2" color="navy"><strong>Jagger Software Ltd</strong></font></td></tr><tr><td><font face="Arial,sans-serif" size="2" color="navy"><strong>Company # 4070126</strong></font></td></tr><tr><td><font face="Arial,sans-serif" size="2" color="navy"><strong>VAT # 762 5213 42</strong></font></td></tr></table><img src="valid-html401.png" align="left" height="31" width="88" alt="Valid HTML 4.01" /><img src="vcss.gif" align="left" height="31" width="88" alt="Valid CSS" /></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -