Почему я НЕ получать предупреждения о неинициализированных полях только для чтения?

Компилятор C # достаточно любезен, чтобы дать вам предупреждение «поле никогда не назначается», если вы забыли инициализировать член, доступный только для чтения, который является частным или внутренним, или если класс, в котором он объявляется является внутренним. Но если класс является общедоступным, а член, доступный только для чтения, является общедоступным, защищенным или защищенным внутренним, тогда никаких предупреждений для вас!

Кто-нибудь знает, почему?

Пример кода, который демонстрирует оценивает условия, при которых выдается предупреждение, и условия, при которых предупреждение не выдается:

namespace Test1 
{ 
    class Test1
    { 
#if TRY_IT 
        public readonly int m; //OK: warning CS0649: Field is never assigned to, and will always have its default value 0 
        protected readonly int n; //OK: warning CS0649: Field is never assigned to, and will always have its default value 0 
        internal readonly int o; //OK: warning CS0649: Field is never assigned to, and will always have its default value 0 
        private readonly int p; //OK: warning CS0649: Field is never assigned to, and will always have its default value 0 
        protected internal readonly int q; //OK: warning CS0649: Field is never assigned to, and will always have its default value 0 

        Test1()
        {
            if( p != 0 ) //To avoid warning 'The field is never used'
                return;
        }
#endif
    } 

    public class Test2
    { 
#if TRY_IT 
        private readonly int m; //OK: warning CS0649: Field is never assigned to, and will always have its default value 0 
        internal readonly int n; //OK: warning CS0649: Field is never assigned to, and will always have its default value 0 

        Test2()
        {
            if( m != 0 ) //To avoid warning 'The field is never used'
                return;
        }
#endif 
        public readonly int o; //Blooper: no warning about field never assigned to. 
        protected readonly int p; //Blooper: no warning about field never assigned to. 
        protected internal readonly int q; //Blooper: no warning about field never assigned to.
    } 

    public sealed class Test3
    { 
        public readonly int m; //Blooper: no warning about field never assigned to. 
    } 
} 

РЕДАКТИРОВАТЬ: На мгновение вы можете подумать, что компилятор воздерживается от выдачи предупреждения в случае публичного и защищенного члены, потому что разумно ожидать, что производные классы могут инициализировать поле.Эта теория не выдерживает критики по ряду причин:

  • Внутренний класс может быть разделен на подклассы, но компилятор этого не делает. в этом случае воздержитесь от предупреждения.

  • Компилятор не может выдать предупреждение даже в случае запечатанного class, как демонстрирует Test3 в примере кода.

  • Предупреждение имеет смысл ради целостности базы. class независимо от того, что производный класс может или не может делать.

  • Язык явно запрещает классу инициализировать только для чтения член базового класса. (Спасибо, Джим Мишель.)

EDIT2: Если мне не изменяет память, Java выдает все надлежащие предупреждения во всех случаях, независимо от того, является ли неинициализированный конечный член общедоступным, защищенным или частным, и независимо от того, является ли неинициализированный конечный член общедоступным, защищенным или частным. содержащий его класс является общедоступным или видимым только внутри своего пакета.

21
задан Eric Lippert 31 December 2011 в 15:49
поделиться