public
を明示的に実装するクラスでinterface
メソッドを作成しているときにこのエラーが発生します。回避策があります:PrintName
メソッドの明示的な実装を削除することにより。しかし、なぜこのエラーが発生するのか、驚きました。
誰でもエラーを説明できますか?
ライブラリのコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test.Lib1
{
public class Customer : i1
{
public string i1.PrintName() //Error Here...
{
return this.GetType().Name + " called from interface i1";
}
}
public interface i1
{
string PrintName();
}
interface i2
{
string PrintName();
}
}
コンソールテストアプリケーションのコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Test.Lib1;
namespace ca1.Test
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
Console.WriteLine(customer.PrintName());
//i1 i1o = new Customer();
//Console.WriteLine(i1o.printname());
//i2 i2o = new Customer();
//Console.WriteLine(i2o.printname());
}
}
}
explicitインターフェースの実装を使用すると、メンバーはクラス自体でprivateよりも制限されたものに強制されます。また、アクセス修飾子が強制されている場合、追加することはできません。
同様に、インターフェース自体では、すべてのメンバーはpublicです。インターフェイス内に修飾子を追加しようとすると、同様のエラーが発生します。
明示的なメンバーが(非常に)プライベートなのはなぜですか?考慮してください:
_interface I1 { void M(); }
interface I2 { void M(); }
class C : I1, I2
{
void I1.M() { ... }
void I2.M() { ... }
}
C c = new C();
c.M(); // Error, otherwise: which one?
(c as I1).M(); // Ok, no ambiguity.
_
これらのメソッドがパブリックである場合、通常のオーバーロードルールでは解決できない名前の衝突が発生します。
同じ理由で、_class C
_メンバー内からM()
を呼び出すことさえできません。同じ曖昧さを避けるために、最初にthis
を特定のインターフェースにキャストする必要があります。
_class C : I1, I2
{
...
void X()
{
M(); // error, which one?
((I1)this).M(); // OK
}
}
_
http://msdn.Microsoft.com/en-us/library/aa288461(VS.71).aspx :メンバーが明示的に実装されている場合、メンバーはクラスインスタンスを介してアクセスできませんが、インターフェイスのインスタンスを介して。
_Customer customer = new Customer();
_
Console.WriteLine(customer.PrintName());
これに違反する
インターフェイスを明示的に実装する場合、アクセス修飾子を使用できません。いずれにせよ、メンバーはインターフェイスにバインドされるため、すべてのインターフェイスメンバーは常にパブリックであるため、アクセス修飾子を指定する必要はありません。また、明示的に実装されたすべてのメンバーは、インターフェイスタイプのメンバーを通じてのみアクセスできます(statichippoの回答を参照)。