の違いは何ですか?とのインターフェイスを明示的に実装します。を実装します。C#インターフェイスの暗黙実装と明示実装の違い
インターフェイスからクラスを派生させるとき、intellisenseは両方を行うことを提案します。
しかし、違いは何ですか?
の違いは何ですか?とのインターフェイスを明示的に実装します。を実装します。C#インターフェイスの暗黙実装と明示実装の違い
インターフェイスからクラスを派生させるとき、intellisenseは両方を行うことを提案します。
しかし、違いは何ですか?
本の別の側面にこのコードを検討し、関数名に完全修飾名を置く:あなたは暗黙的にが実装場合
を、それはインターフェースのメンバーがにアクセス可能であることを意味しあなたのクラスのユーザーは、キャストする必要はありません。
が明示的に実装されている場合、クライアントはメンバーにアクセスできるようにクラスをインターフェイスにキャストする必要があります。インタフェースが直交するとき、最も有用である
interface Animal
{
void EatRoots();
void EatLeaves();
}
interface Animal2
{
void Sleep();
}
class Wombat : Animal, Animal2
{
// Implicit implementation of Animal2
public void Sleep()
{
}
// Explicit implementation of Animal
void Animal.EatRoots()
{
}
void Animal.EatLeaves()
{
}
}
あなたのクライアントコードを明示的にキャストしない限り、実装が隠されている
Wombat w = new Wombat();
w.Sleep();
w.EatRoots(); // This will cause a compiler error because it's explicitly implemented
((Animal)w).EatRoots(); // This will compile
ここでは、違いはあなたがいくつかのインタフェースからクラスを継承することができるということですMSDN
から直接、行きます。これらのインタフェースは、同一のメソッドシグネチャを持つことができます。明示的な実装では、Interfaceの呼び出しに応じて実装を変更することができます。
ExplicitはIInterfaceNameを指定します。すべてのインタフェース実装の前面に表示されます。衝突する名前/シグネチャを含む2つのインタフェースを実装する必要がある場合に便利です。
詳細情報here。
IDEには、オプションがあります。両方を行うことは珍しいことです。明示的な実装では、メンバーは(プライマリ)パブリックAPIにはありません。これは、インタフェースがオブジェクトの意図に直接結ばれていないと便利です。たとえば、ICustomTypeDescriptor
のメンバーは、通常の発信者にとって役立つものではありません。特定の特定のコードに対してのみ使用できます。そのため、パブリックAPIに混乱を招くような目的はありません。
また、これは場合に便利です:
Foo
方法と、独自のタイプのFoo
方法の間に矛盾がある、と彼らは異なることを意味最後のポイントの典型的な例はIEnumerable<T>
であり、これはインターフェイス階層の2つのレベルでGetEnumerator()
メソッドを持ちます。これはimpl暗黙の実装を使用して型付き(IEnumerator<T>
)バージョンを、明示的実装を使用して型なし(IEnumerator
)バージョンを作成します。
明示的に実装するには
public interface IamSam
{
int foo();
void bar();
}
public class SamExplicit : IamSam
{
#region IamSam Members
int IamSam.foo()
{
return 0;
}
void IamSam.bar()
{
}
string foo()
{
return "";
}
#endregion
}
public class Sam : IamSam
{
#region IamSam Members
public int foo()
{
return 0;
}
public void bar()
{
}
#endregion
}
IamSam var1;
var1.foo() returns an int.
SamExplicit var2;
var2.foo() returns a string.
(var2 as IamSam).foo() returns an int.
明示的なインターフェイスの実装、: はここに明示的な実装の一例ですクラスの機能。つまり、行動的に無関係です。
たとえば、クラスがPersonでインターフェースがISerializableの場合、Person属性を扱う人がIntellisenseを介して 'GetObjectData'という名前の奇妙なものを見るのはあまり意味がありません。したがって、明示的にインターフェイスを実装したいことがあります。
一方、PersonクラスがIAddressを実装した場合、PersonインスタンスのAddressLine1、ZipCodeなどのメンバーを直接(暗黙の実装)見ることは理にかなっています。ここで
は平易な英語の違いです:
は、関数Run()
、ともRun()
呼ばれる機能を持っている別のインターフェイスAnimal
を持つインタフェースMachine
を、持っていると仮定します。もちろん、機械が走っている時、私たちはそれについて話していますが、動物が走ったら、動き回っていると話しています。オブジェクトを持っているとどうなりますか?Aibo
と呼びましょう。Machine
とAnimal
です。 (ちなみに、アイボは機械的な犬です。)Aibo
が走ると、彼は立ち上がりますか、動いていますか?
interface Animal
{
void Run();
}
interface Machine
{
void Run();
}
class Aibo : Animal, Machine
{
void Animal.Run()
{
System.Console.WriteLine("Aibo goes for a run.");
}
void Machine.Run()
{
System.Console.WriteLine("Aibo starting up.");
}
}
class Program
{
static void Main(string[] args)
{
Aibo a = new Aibo();
((Machine)a).Run();
((Animal)a).Run();
}
}
ここでキャッチ機能の私の実装の両方が明示的インターフェイスに接続されているので、私は単にa.Run()
を呼び出すことはできませんということです:明示的インターフェイスを実装することで、その区別を行うことができます。そうでなければ、コンパイラはどちらを呼び出すべきかを知っているでしょうか?代わりに、Aibo
のRun()
関数を直接呼びたい場合は、に明示的なインターフェイスなしで実装する必要があります。
明示的な実装は、アセンブリからパブリックにエクスポートしたくない内部インターフェイスをクラスが実装する必要がある場合にも便利です。 – Dave