What is the difference between method hiding and shadowing in C#? Are they same or different? Can we call them as polymorphism (compile time or run time)?
5 に答える
C#でのメソッドの隠蔽とシャドウイングの違いは何ですか?
シャドウイングは、非表示を表すもう 1 つの一般的な用語です。C# 仕様では「非表示」のみが使用されますが、どちらでもかまいません。
「メソッドの隠蔽」と呼んでいますが、メソッドの隠蔽以外にも隠蔽の形式があります。例えば:
namespace N
{
class D {}
class C
{
class N
{
class D
{
N.D nd; // Which N.D does this refer to?
ネストされたクラス N は、D 内にある場合、名前空間 N を隠します。
それらをポリモーフィズム (コンパイル時または実行時) と呼べますか?
はい、メソッドの隠蔽は多態性に使用できます。メソッドの非表示とメソッドのオーバーライドを混在させることもできます。古い仮想メソッドを隠して新しい仮想メソッドを導入することは合法です。その場合、どの仮想メソッドが選択されるかは、レシーバーのコンパイル時および実行時のタイプによって異なります。これを行うと非常に混乱するため、可能であれば避ける必要があります。
VB.NET コンパイラはこれをシャドーイングと呼び、C# ではハイディングと呼びます。C# でシャドーイングと呼ぶのは、VB からのスピルオーバーです。
これはコンパイラの警告であり、基本的には基本クラスと派生クラスの間の名前の競合です。
それらをポリモーフィズム (コンパイル時または実行時) と呼べますか?
これは確かに、ランタイム ポリモーフィズムの形式ではありません。非表示または非表示のメソッドへの呼び出しは、コンパイル時に解決されます。これにより、一般にポリモーフィズムと呼ばれたり、ポリモーフィズムと見なされたりすることはありません。
C# の名前隠蔽 (new
修飾子) は、VB.NET ではシャドウイング (キーワードShadows
) と呼ばれます。
これは、オーバーライドが「ポリモーフィズム」、つまり静的またはコンパイル時であるという意味でのみ、ポリモーフィズムと考えることができます。これは、仮想関数を呼び出すという古典的な意味でのポリモーフィズムではありません。
これらは同じものを表す 2 つの異なる単語ですが、最も頻繁に使用するコンテキストが異なります。通常、「隠蔽」と呼ばれるものはポリモーフィズムに関連していますが、「シャドウイング」と呼ばれるものはそうではありません。
C# の用語では、「非表示」と言うときは、通常、継承について話していることになります。つまり、より派生したメソッドが、通常の継承されたメソッド呼び出しチェーンから基本クラスのメソッドを「非表示」にします。
「シャドウ」と言うとき、通常はスコープについて話しています。内側のスコープの識別子は、より高いスコープの識別子を「シャドウイング」しています。他の言語では、C# で「非表示」と呼ばれるものは、「シャドーイング」と呼ばれることもあります。
どちらもコンパイル時の概念です。それらは、コンパイラーが特定の識別子をバインドするときに、特定のコンテキストで特定の識別子が参照するオブジェクトを記述します。
public class A
{
public int B;
public void C()
{
return this.B;
}
}
public class D : A
{
public int X;
public new void C()
{
var X = 1.0m;
return X;
}
}
メソッドはメソッドD.C()
を「隠します」A.C()
。通常、 への呼び出しは、 ではないためD.C()
、常に基本クラスA.C()
のメソッドを呼び出しvirtual
ます。私たちはそれを望んでいません。私たちは欲しいD.C()
。特に D を A にアップキャストする場合は混乱を招くため、明らかにこれは避けるべきですが、必要に応じて存在します。また、メソッドの非表示は自動的に行われることに注意してください。new
ここにキーワードがなくてD.C()
も非表示になりますが、通常はA.C()
それが望ましくないため、警告が表示されます。キーワードは、それが本当に私たちが望んでいるものであることを明確にしています。new
onlyのスコープ内のX
シャドウD.C()
クラス メンバーのローカル変数。この場合、スコープ内に正当に呼び出される可能性のあるものが 2 つあり、コンパイラはどちらを意味するかを伝えるルールが必要です。「ローカル性が高い」は「ローカル性が低い」の影になるので、それが得られます。D.X
D.C()
X
X
D.X
この 2 つの用語は、C# では同じ意味です。
メソッドの隠蔽 == シャドーイング。
これをポリモーフィズムの形式として使用できます-継承クラスを通じて基本クラスのメソッドを表示/使用可能にしたくない場合。
シャドウイング メソッドは、基本クラスから完全に分離されています。これは新しいメソッドです。非表示という用語が使用されるのは、基本クラスのシグネチャと同一のシグネチャを持ち、それを「隠蔽」しているためです。つまり、継承チェーンが壊れます。