Как сделать свойство защищенным И внутренним в C#?

Как бы глупо это не звучало, Мне пришлось выбрать другой файл на боковой панели слева и вернуться к моему файлу с контрольными примерами. После этого кнопка сразу стала активной.

28
задан Martin Backasch 18 July 2018 в 10:16
поделиться

4 ответа

Что плохого в том, чтобы сделать геттер открытым? Если вы объявляете свойство как

public string[] Headers { get; protected set; }

, оно удовлетворяет всем необходимым критериям: все члены сборки могут получить свойство, и только производные классы могут его устанавливать. Конечно, классы вне сборки также могут получить свойство. Итак?

Если вам действительно нужно раскрыть свойство в вашей сборке, но не публично, другой способ сделать это - создать другое свойство:

protected string[] Headers { get; set; }
internal string[] I_Headers { get { return Headers; } }

Конечно, это некрасивое украшение имени этим I_ префикс. Но это какой-то странный дизайн. Изменение имени внутреннего свойства - это способ напомнить себе (или другим разработчикам), что свойство, которое они используют, является неортодоксальным. Кроме того, если позже вы решите, что подобная смешанная доступность на самом деле не является правильным решением вашей проблемы, вы будете знать, какие свойства нужно исправить.

Уродливое украшение имени префиксом I_ . Но это какой-то странный дизайн. Изменение имени внутреннего свойства - это способ напомнить себе (или другим разработчикам), что свойство, которое они используют, является неортодоксальным. Кроме того, если позже вы решите, что подобная смешанная доступность на самом деле не является правильным решением вашей проблемы, вы будете знать, какие свойства нужно исправить.

Уродливое украшение имени префиксом I_ . Но это какой-то странный дизайн. Изменение имени внутреннего свойства - это способ напомнить себе (или другим разработчикам), что свойство, которое они используют, является неортодоксальным. Кроме того, если позже вы решите, что подобная смешанная доступность на самом деле не является правильным решением вашей проблемы, вы будете знать, какие свойства нужно исправить.

16
ответ дан 28 November 2019 в 02:48
поделиться

Это невозможно в C #.

Для полноты картины это поддерживается в IL (модификатор доступа к семейству и сборке).

31
ответ дан 28 November 2019 в 02:48
поделиться

I would keep the access modifier as protected and have an internal helper method.

protected override string[] Headers {
    get { return headers; } // Note that get is protected
    set { headers = value; }
}

internal SetHeadersInternal(string[] newHeaders)
{
    headers = newHeaders;
}

But somehow, this smells like it should be refactored somehow. Internal is always something I'd use sparingly because it can lead to a very messy architecture where everything is somehow using everything else within the assembly, but of course there's always exceptions.

6
ответ дан 28 November 2019 в 02:48
поделиться

Принято считать, что нельзя сделать некоторых членов одновременно защищенными И внутренними.

И это правда, что вы не можете сделать это одной строкой, как многие, включая меня, хотели бы, но при некотором умении это выполнимо на 100%.

//Code below is 100% tested

/* FROM ProtectedAndInternal.dll */

namespace ProtectedAndInternal
{
    public class MyServiceImplementationBase
    {
        protected static class RelevantStrings
        {
            internal static string AppName = "Kickin' Code";
            internal static string AppAuthor = "Scott Youngblut";
        }
    }

    public class MyServiceImplementation : MyServiceImplementationBase
    {
        public void PrintProperties()
        {
            // WORKS PERFECTLY BECAUSE SAME ASSEMBLY!
            Console.WriteLine(RelevantStrings.AppAuthor);
        }
    }

    public class NotMyServiceImplementation
    {
        public void PrintProperties()
        {
            // FAILS - NOT THE CORRECT INHERITANCE CHAIN
            // Error CS0122: 'ProtectedAndInternal.MyServiceImplementationBase.Relevant' is inaccessible due to its protection level
            // Console.WriteLine(MyServiceImplementationBase.RelevantStrings.AppAuthor);
        }
    }
}



/* From AlternateAssemblyService.dll which references ProtectedAndInternal.dll */

namespace AlternateAssemblyService
{
    public class MyServiceImplementation : MyServiceImplementationBase
    {
        public void PrintProperties()
        {
            // FAILS - NOT THE CORRECT ASSEMBLY
            // Error CS0117: 'ProtectedAndInternal.MyServiceImplementationBase.RelevantStrings' does not contain a definition for 'AppAuthor'
            // Console.WriteLine(RelevantStrings.AppAuthor);
        }
    }
}
2
ответ дан 28 November 2019 в 02:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: