接口成员的访问
在实现接口时,可以在类中声明显式接口成员实现。 以下介绍两个概念:
显式接口成员实现:就是在类中声明方法,属性,事件或索引器时,使用显式接口成员完全限定名作为标识符。
显式接口成员:以显式接口成员实现的成员。
显式接口成员完全限定名构成:【声明该成员的接口名称】.【成员名】
实现一个显示接口成员需要注意:1.在实现接口的类的基类列表中指定一个接口,而且该接口必须包含一个与该显式接口成员完全限定名,类型,参数类型完全相同的成员。接口成员完全限定名必须引用声明该成员的接口。
2.在显示接口成员实现中不能包含访问修饰符,abstract,override或static修饰符。
3.从本质上来说,显式接口成员属于接口的成员,而不是类的成员。因此不能使用类实例来直接访问,只能通过接口的实例来访问。并且通过接口实例来访问时,只能用该接口成员的简单名称来引用。
4.实现显式接口成员的类中可以进行this访问,需要将this显式的转化为接口实例后进行引用。
5.显示接口成员可以消除因同时含有多个签名相同的接口成员所引起的多义性。使一个类能够为具有相同签名多个接口成员分别提供相应的实现(包含返回类型相同或不相同)。
6.使用显式接口成员实现可以实现一个被隐藏的接口成员。
7.显式的接口成员不能声明为虚方法,因此不能重写显式接口成员。但是可以通过在显示接口成员的内部调用另一个虚方法,派生类可以通过重写该方法达到重写显式接口成员的目的。
以下的是我测试的代码,只是为了达到测试目的(大综合了一下)
,所以很乱,可以参考一下
using System;
namespace Eximember
{
interface Itestone
{
string Copy(int c);
}
interface Itesttwo
{
int Add(int a, int b);
}
interface Itestthree
{
void Copy(int c);
}
interface Itestfour
{
string Copy(int c);
}
interface Ione
{
int P
{
get;
}
void Paint();
}
interface Itwo : Ione
{
new int P();//隐藏显示接口成员测试
}
class Display : Itestone, Itesttwo, Itestthree, Itestfour
{
string Itestone.Copy(int c)
{
return c.ToString();
}
string Itestfour.Copy(int c)
{
return Convert.ToString(c);
}
void Itestthree.Copy(int c)
{
Console.WriteLine(c);
}
public void Copy()
{
Console.WriteLine("Display.Copy()");
}
/*以上为测试显式接口成员实现消除因含有多个
* 签名相同的成员而存在多义性而报错*/
int Itesttwo.Add(int a, int b)
{
return a + b;
}
public void Test()
{/*错误:不能直接访问显式接口成员
object o1 = Copy(int 5);
* 错误:不能通过完全限定名来访问显示接口成员
object o2=Itesttwo.Add(int 3,int 5);*/
object o3 = ((Itesttwo)this).Add(5, 3);
//使用对应的接口实例来访问
Console.WriteLine(o3);
}
}
class Hidembr : Itwo
{
int Ione.P { get { return 123; } }
int Itwo.P()
{
return 123;
}
void Ione.Paint()
{
RePaint();
}
protected internal virtual void RePaint()
{
Console.WriteLine("Ione.Paint()");
}
class Revir: Hidembr
{
protected internal override void RePaint()
{
Console.WriteLine("Revir.RePaint()");
}
}
class Test
{
public static void Main()
{
Display dp = new Display();
/*错误:不能用类的实例直接访问显式接口成员
* object o = dp.Copy(3);
int n = dp.Add(3,5);*/
//正确使用对应的接口访问
object o = ((Itestone)dp).Copy(12345);
int n = ((Itesttwo)dp).Add(123, 456);
Itestone ito = dp;
Itesttwo itt = dp;
//使用对应的接口实例来访问
string str = ito.Copy(5);
int d = itt.Add(3, 5);
//测试消除多义性
Itestthree ith = dp;
Itestfour itf = dp;
string s;
ith.Copy(3);
dp.Copy();
s = itf.Copy(5);
Console.WriteLine(s);
Console.WriteLine(o);
Console.WriteLine(n);
Console.WriteLine(str);
Console.WriteLine(d);
dp.Test();
Hidembr hi = new Hidembr();
Revir re = new Revir();
Ione ir = re;
Ione ih = hi;
ih.Paint();
ir.Paint();
Console.ReadKey();
}
}
}
}
7.接口成员的隐藏可以在一系列的继承类中在方法签名相同的情况下实施多态,同时访问需要使用显示的接口成员实现,但是对于方法签名不同的接口成员,在继承接口或者独立接口中都不需要隐藏,根据重载决策规则不会产生多义性。
namespace Eximember
{
interface Itestone
{
string Copy(int c);
}
interface Itesttwo
{
int Add(int a, int b);
}
interface Itestthree
{
void Copy(int c);
}
interface Itestfour
{
string Copy(int c);
}
interface Ione
{
int P
{
get;
}
void Paint();
}
interface Itwo : Ione
{
new int P();//隐藏显示接口成员测试
}
class Display : Itestone, Itesttwo, Itestthree, Itestfour
{
string Itestone.Copy(int c)
{
return c.ToString();
}
string Itestfour.Copy(int c)
{
return Convert.ToString(c);
}
void Itestthree.Copy(int c)
{
Console.WriteLine(c);
}
public void Copy()
{
Console.WriteLine("Display.Copy()");
}
/*以上为测试显式接口成员实现消除因含有多个
* 签名相同的成员而存在多义性而报错*/
int Itesttwo.Add(int a, int b)
{
return a + b;
}
public void Test()
{/*错误:不能直接访问显式接口成员
object o1 = Copy(int 5);
* 错误:不能通过完全限定名来访问显示接口成员
object o2=Itesttwo.Add(int 3,int 5);*/
object o3 = ((Itesttwo)this).Add(5, 3);
//使用对应的接口实例来访问
Console.WriteLine(o3);
}
}
class Hidembr : Itwo
{
int Ione.P { get { return 123; } }
int Itwo.P()
{
return 123;
}
void Ione.Paint()
{
RePaint();
}
protected internal virtual void RePaint()
{
Console.WriteLine("Ione.Paint()");
}
class Revir: Hidembr
{
protected internal override void RePaint()
{
Console.WriteLine("Revir.RePaint()");
}
}
class Test
{
public static void Main()
{
Display dp = new Display();
/*错误:不能用类的实例直接访问显式接口成员
* object o = dp.Copy(3);
int n = dp.Add(3,5);*/
//正确使用对应的接口访问
object o = ((Itestone)dp).Copy(12345);
int n = ((Itesttwo)dp).Add(123, 456);
Itestone ito = dp;
Itesttwo itt = dp;
//使用对应的接口实例来访问
string str = ito.Copy(5);
int d = itt.Add(3, 5);
//测试消除多义性
Itestthree ith = dp;
Itestfour itf = dp;
string s;
ith.Copy(3);
dp.Copy();
s = itf.Copy(5);
Console.WriteLine(s);
Console.WriteLine(o);
Console.WriteLine(n);
Console.WriteLine(str);
Console.WriteLine(d);
dp.Test();
Hidembr hi = new Hidembr();
Revir re = new Revir();
Ione ir = re;
Ione ih = hi;
ih.Paint();
ir.Paint();
Console.ReadKey();
}
}
}
}
7.接口成员的隐藏可以在一系列的继承类中在方法签名相同的情况下实施多态,同时访问需要使用显示的接口成员实现,但是对于方法签名不同的接口成员,在继承接口或者独立接口中都不需要隐藏,根据重载决策规则不会产生多义性。
using System;
namespace Ifmaccess
{
interface IBase
{
void F(int c);
}
interface ILeft : IBase
{
new void F(int i);
}
interface IRight : IBase
{
void G();
}
interface ISub : ILeft, IRight
{
}
class A
{
void Test(ISub x)
{
x.F(3); //ILeft.F()
((IBase)x).F(3); //IBase.F();
((ILeft)x).F(3); //ILeft.F();
((IRight)x).F(3); //IBase.F();
}
public static void Main()
{
A a = new A();
B b = new B();
a.Test(b);
Console.ReadKey();
}
}
class B : ISub
{
void IBase.F(int c)
{
Console.WriteLine("IBase.F()");
}
void ILeft.F(int c)
{
Console.WriteLine("ILeft.F()");
}
public void G()
{
Console.WriteLine("IRight.G()");
}
}
}
namespace Ifmaccess
{
interface IBase
{
void F(int c);
}
interface ILeft : IBase
{
new void F(int i);
}
interface IRight : IBase
{
void G();
}
interface ISub : ILeft, IRight
{
}
class A
{
void Test(ISub x)
{
x.F(3); //ILeft.F()
((IBase)x).F(3); //IBase.F();
((ILeft)x).F(3); //ILeft.F();
((IRight)x).F(3); //IBase.F();
}
public static void Main()
{
A a = new A();
B b = new B();
a.Test(b);
Console.ReadKey();
}
}
class B : ISub
{
void IBase.F(int c)
{
Console.WriteLine("IBase.F()");
}
void ILeft.F(int c)
{
Console.WriteLine("ILeft.F()");
}
public void G()
{
Console.WriteLine("IRight.G()");
}
}
}
interface IA
{
void F();
}
interface IB:IA
{
new void F();
}
class C : IB
{
public void F()
{
Console.WriteLine("C.F()");
}
}
{
void F();
}
interface IB:IA
{
new void F();
}
class C : IB
{
public void F()
{
Console.WriteLine("C.F()");
}
}