(РЕДАКТИРОВАТЬ: я только что проверил, и это работает, даже когда тип свойства совпадает с объявленным типом. Однако, не работает, когда вы пытаетесь объявить свойство в типе public , где типом свойства является внутренний тип.)
Вы не можете сделать это в C # (строго говоря), но вы можете сделать что-то очень похожее:
protected internal int Length { get; protected set; }
(Это используется автоматически реализованным свойством только для простоты; тот же метод будет работать и для «нормального» свойства.)
Это сделает «геттер» доступным для любого типа в пределах одной и той же сборки и производных типов; «Сеттер» будет доступен только для производных типов. Так как ваш класс в любом случае является внутренним, это все равно в значительной степени эквивалентно - теоретически, метод получения будет доступен для типов вне сборки, но, поскольку класс является внутренним, ничто из другой сборки не должно быть производным от вашего типа.
Проблема в том, что свойства требуют, чтобы один уровень доступа был «подмножеством» другого; internal
и protected
не работают так - один тип может быть в одной сборке, но не может быть получен из рассматриваемого типа; из него может быть получен другой тип, но в другой сборке. В основном они ортогональны.
Приведенное выше решение работает, потому что protected internal
означает, что оно доступно для любого типа, который или в той же сборке или , полученного из типа. Очевидно, что каждый из protected
и internal
в отдельности является подмножеством этого.
Вы могли бы создать свойство internal
, которое было бы дополнительно ограничено для установщика, если бы C # имел некоторый эквивалент уровня доступа CLR "семейство и сборка". (protected internal
эквивалентно «семейству или сборки».) К сожалению, для вас это не так: (
Если вы действительно хотите первоначально заявленные цели (например, если у вас позже есть публичный класс, к которому вы хотите применить те же ограничения), вам придется сделать хотя бы один из них отдельным методом вместо этого, например
private int length;
internal int Length { get { return length; } }
protected void SetLength(int value)
{
this.length = value;
}