Что плохого в том, чтобы обнародовать геттер? Если вы объявите свойство как
public string[] Headers { get; protected set; }
оно соответствует всем необходимым критериям: все члены сборки могут получить свойство, и только производные классы могут установить его. Конечно, классы вне сборки тоже могут получить свойство. Так?
Если вам действительно необходимо выставить свойство в пределах вашей сборки, но не публично, другой способ сделать это - создать другое свойство:
protected string[] Headers { get; set; }
internal string[] I_Headers { get { return Headers; } }
Конечно, некрасиво украшать имя этим префиксом I_
. Но это довольно странный дизайн. Выполнение какого-либо искажения имени во внутреннем свойстве - это способ напомнить себе (или другим разработчикам), что свойство, которое они используют, неортодоксально. Кроме того, если позже вы решите, что смешанная доступность не является правильным решением вашей проблемы, вы будете знать, какие свойства нужно исправить.