Это просто два разных слова для одной и той же вещи, но они отличаются в контексте, в котором вы их чаще всего используете.Как правило, то, что называется «скрытием», связано с полиморфизмом, но то, что называется «теневым», не является.
На языке 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 на А, но оно существует, если вам это нужно.Также обратите внимание, что скрытие метода происходит автоматически: без ключевого слова new
здесь D.C()
все еще скрывает A.C()
, но мы получаем предупреждение, потому что обычно это не то, что вам нужно.Ключевое слово new
просто дает понять, что это именно то, что нам нужно.
Локальная переменная X
в D.C()
член класса теней D.X
только в области действия D.C()
.В этом случае есть две вещи в области видимости, которые можно было бы по праву назвать X
, и компилятору нужны правила, чтобы сказать, какую именно вы имеете в виду.«Более локальный» X
затеняет «менее локальный» D.X
, так что вот что мы получаем.