次のコードがあるとします。
class Foo: IFoo {
public string fooProp { get; set; }
}
interface IFoo {
string fooProp {get; set; }
}
次の間に異なる動作が発生する可能性はありますか?
Foo x = new Foo();
someMethod(x);
と:
IFoo x = new Foo();
someMethod(x);
?
次のコードがあるとします。
class Foo: IFoo {
public string fooProp { get; set; }
}
interface IFoo {
string fooProp {get; set; }
}
次の間に異なる動作が発生する可能性はありますか?
Foo x = new Foo();
someMethod(x);
と:
IFoo x = new Foo();
someMethod(x);
?
違う場合もあると思います。誰かが悪いスタイルのプログラミングを使用した場合、つまり:
public void someMethod(IFoo f)
{
if (f is Foo)
{
Foo f1 = (Foo)f;
//Do smth with unique Foo members
}
//Do anything with IFoo members
}
someMethod
はい、とのオーバーロードが異なる場合は違いがIFoo
ありFoo
ます。
public void someMethod(Foo f)
{
// Overload 1
}
public void someMethod(IFoo f)
{
// Overload 2
}
Foo x = new Foo();
someMethod(x); // Matches overload 1
IFoo x = new Foo();
someMethod(x); // Matches overload 2
違いはありません。
インターフェイスはコントラクトであることを忘れないでください。Foo
から派生することにより、そのコントラクトIFoo
を実装しています。
どちらの場合も、はとが契約に準拠しているFoo
ため、動作は常に同じになります。 IFoo
もちろん、Fooがその契約をどのように実装するかは誰もが推測します。しかし、契約はインターフェースの署名によっても守られています。
異なる動作をすることができますが、内部someMethod
です。
あなたが持っていると言う
class Foo: IFoo {
public fooProp { get; set; }
}
interface IFoo {
fooProp {get; set; }
myCustomProp {get;set}
}
あなたが持っている場合
public void someMethod(Foo _foo){
_foo.myCustomProp; //CAN DO THIS, AS YOUR TYPE IS _FOO_
}
メソッドのパラメータがのように定義されている場合、これは不可能です。
public void someMethod(IFoo _foo){
_foo.myCustomProp; //NO SUCH METHOD INFO
}
キャストしない限り。したがって、違いは、IFooをデケアして、汎用アクセスパラメータをデカールしますが、データアクセスに関しては「可能性」が低くなりますが、アーキテクチャの型よりも抽象化の可能性が非常に高くなることです。
したがって、違いはアーキテクチャとプログラムワークフローに関してのみです。
Foo で明示的に実装されたインターフェースを持つことができます。
class Foo: IFoo {
private string _fooprop;
private string _ifooprop;
public string fooProp
{
get {return "IFoo";}
set {_fooprop=value;}
}
string IFoo.fooProp
{
get {return "Foo";}
set {_ifooprop=value;}
}
}
interface IFoo {
string fooProp {get; set; }
}
これにより、次のものが得られます。
IFoo foo1=new Foo();
Foo foo2=new Foo();
Console.WriteLine(foo1.fooProp); // Foo
Console.WriteLine(foo2.fooProp); // iFoo
2 つのインターフェイスがあり、それぞれに共通のメソッド名がある場合、実装クラスは同じメソッドを異なる方法で実装できます。メソッドがどのように呼び出されるかによって異なります-インターフェイスを介してかどうか、およびどのインターフェイスを介してか。
同様の質問については、こちらを参照してください。
(私は専門家ではありません) しかし、最初のシナリオでは、クラス Foo のすべてにアクセスできます。2 番目のシナリオでは、IFoo メンバーにのみアクセスできます。したがって、Foo に (インターフェースの一部ではない) 追加のメソッドがある場合、最初のシナリオではそれらにアクセスできますが、2 番目のシナリオではアクセスできません。
クラス名の代わりにインターフェイス名を使用することは、データをカプセル化し、インターフェイス メンバーへのアクセスのみを提供する別の方法にすぎないと思います。たとえば、どちらも IFoo を実装する Foo と Bar を持つことができます。たとえば、リストに両方を追加できます。
明示的に実装すると可能ですIFoo
:
public class Foo : IFoo
{
public string Prop
{
get { return "Hello Foo"; }
}
string IFoo.Prop
{
get { return "Hello IFoo"; }
}
}
public static void SomeMethod<T>(T foo) where T : IFoo
{
var prop = typeof(T).GetProperty("Prop");
Console.WriteLine(prop.GetValue(foo));
}