По определению, private
членов не являются допустимыми. Если вы хотите, чтобы сеттер был перегружаемым, вы можете пометить его protected
вместо private
.
private abstract class InheritanceTest
{
public virtual object Property
{
get { return null; }
protected set { }
}
public class Child : InheritanceTest
{
public override object Property
{
get { return null; }
protected set { base.Property = null; }
}
}
}
Чтобы более конкретно ответить на ваш вопрос, почему:
Поймите, что, когда ваш код C# компилируется в IL код, там на самом деле заканчивается время 3 вещи 1 собственности.
Property
Имущество непосредственно.
- Метод с именем
get_Property()
, который является геттером.
- Идентификатор метода
set_Property()
, который является установщиком.
В своем коде, вы сказали, что .NET «Я хочу virtual
собственности. Затем он каскады, что уровень доступа к геттерным и инкубационным методам. На самом деле, в IL коды, свойства не уточняет virtual
вообще .
Для C# код:
public virtual object Property { get; set; }
Сформированный IL-код является:
.property instance object Property() { ... }
.method public hidebysig newslot specialname virtual
instance object get_Property() cil managed
{ ... }
.method public hidebysig newslot specialname virtual
instance object set_Property() cil managed
{ ... }
Обратите внимание, что ключевые слова public
и virtual
применяются как к методу получения, так и к методу setter, но не к самому свойству.
Теперь, изменив свой код C# для:
public virtual object Property { get; private set; }
Вы сказали .NET, что вы хотите, чтобы ваши методы получения и установки быть виртуальными ... однако, то он впадает в private set
, и что уровень доступа переопределяетpublic
и virtual
уровень доступа, для метода сеттера. Таким образом, сгенерированный IL код становится:
.property instance object Property() { ... }
.method public hidebysig newslot specialname virtual
instance object get_Property() cil managed
{ ... }
.method private hidebysig newslot specialname
instance object set_Property() cil managed
{ ... }
Обратите внимание, что в настоящее время set_Property()
private
это, и больше не virtual
. На самом деле невозможно иметь private virtual
в .NET, потому что это не имеет смысла ... это похоже на попытку сказать: «ни один другой класс не может это увидеть ... но производные классы могут переопределить эту вещь, видеть или получать доступ ", что не имеет смысла. Производные классы не могут переопределить то, что они даже не видят.
Ключевое слово protected
является надлежащей заменой в этом случае, поскольку оно сообщает .NET. «Только я и производные классы могут видеть или получать доступ к этому, а производные классы могут переопределять это свойство».
Так что я думаю «короткий» ответ был бы только что был «, потому что это не может быть private
и virtual
в .NET, поэтому компилятор принимает более ограниченный уровень доступа, который вы дали его.
Кроме того, IMO сообщение об ошибке довольно правильно
«Program.InheritanceTest.Child.Property.set»:. не может переопределить унаследовал член «Program.InheritanceTest.Property.set», потому что он не отмечен виртуальное, аннотация, или переопределение
Обратите внимание, что это 'Program.InheritanceTest.Property.set'
, поэтому «.set» в конце ссылается на возможный метод set_Property()
, а не на свойство Property
. И метод set_Property()
отмечен только private
, потому что компилятор .NET видел это и удалил virtual
из этого метода по указанной выше причине. Я полагаю, что было бы разумно иметь предупреждение о компиляторе или что-то сказать, что «виртуальный будет игнорироваться для« набора ».
Надеется, что имеет смысл ...
возможно дубликат [Почему частные виртуальные методы запрещены в C#?] (Http://stackoverflow.com/questions/3082310/why-are-private-virtual- методы-незаконный-в-c) – McKay
Я проголосовал за закрытие этого вопроса как дубликата. Я бы рекомендовал другим сделать то же самое. – McKay