本文介绍了为什么我没有得到有关未初始化的只读域警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! C#编译器是一种足以给你一个场从未分配到如果你忘了初始化一个只读成员是私有或内部,或者如果它被声明的类是内部警告。但是,如果类是公众和只读成员是公共的,受保护的或受保护的内部,那么对你没有警告! 有谁知道为什么吗? 样本代码,演示了在其下发出警告的条件,以及在何种条件下的警告没有发出: 命名空间的Test1 {类测试1 {#如果TRY_IT 公共只读INT米; // OK:警告CS0649:字段永远不会分配给,永远有它的默认值0 只读保护INT N; // OK:警告CS0649:现场从未分配到,并且总是有它的默认值0 内部只读INT O; // OK:警告CS0649:现场从未分配到,并且总是有它的默认值0 私人只读INT磷; // OK:警告CS0649:现场从未分配到,并且总是有它的默认值0 受保护的内部只读INT q; // OK:警告CS0649:现场从未分配到,并且总是有它的默认值0 Test1的() {如果(P!= 0)//为了避免警告字段从未使用过'的回报; } #ENDIF } 公共类的Test2 {#如果TRY_IT 私人只读INT米; // OK:警告CS0649:现场从未分配到,并且总是有它的默认值0 内部只读INT N; // OK:警告CS0649:现场从未分配到,并且总是有它的默认值0 的Test2() {如果(M!= 0)//为了避免警告字段从未使用过'的回报; } #ENDIF 公共只读INT O; //轶事:毫无从未派到外地警告。 保护只读INT磷; //轶事:毫无从未派到外地警告。 受保护的内部只读INT q; //轶事:毫无从未派到外地警告。 } 公共密封类Test3的 {公共只读INT米; //轶事:毫无从未派到外地警告。 } } 编辑:有关那一刻,你可能会认为,从发行受保护的公共成员的情况下,警告,因为它是合理的期望,派生类可能初始化该领域的叠句的编译器。这种理论不持有任何的水有很多原因: 这是内部类可以被继承,但是编译器不从发出在这种情况下,警告副歌。 编译器无法发出警告,即使是在一个密封的级的情况下,Test3的示例代码演示了。 警告有意义基类的完整性的缘故而不管一个派生类可以或不可以做的。 一个类是明确的语言,从初始化基类的只读成员禁止。 (感谢吉姆·米契尔。) EDIT2:如果我没记错的好, Java的提供在所有情况下都正确的警告,无论未初始化的最后一位成员是公共的,受保护的或私有的,也不管包含它的类是否只在其包中的公共或可见。 解决方案 简短的回答:这是在编译器监督 较长的答案:启发式这决定了警告发出成员和当地居民被声明并没有用过,或书面和从来没有读过,或读,从没写过,不走场的只读岬考虑。当你注意到,它可能,从而发出更多的情况下警告。我们可以说,这是不以任何构造函数初始化的公共只读域永远有它的默认值的例子。 我要把它提到尼尔在新的一年,我们将看看我们是否能改善这些罗丝琳启发。 顺便说一下,有一些在这种警告可能发出的情况下(无论只读岬),但我们不这样做。今天我没有在我的办公室,所以我没有我的那些方便的情况列表中,但我只想说有很多人。这是东西像字段被声明为public,是一个公共嵌套类内部类的。在这种情况下该字段为有效的内部,我们可以做的警告,但有时我们不知道。 有一天,很多年前我改变了启发,这样的可能被静态已知每个的领域产生了警告未使用,并且当变化使它成为我们用来编译是用C#类库C#编译器的内部版本,全乱套了。那些家伙始终以警告视为错误编译打开,突然他们开始在所有种类的故意初始化或通过反射ONL使用的字段和其他动态技术得到警告。我的一个主要方式打破了构建。现在,有人可能会争辩说,哎,因此,它抑制了警告,这些人应该解决他们的代码(我确实认为),但最终被证明是更容易背面的警告启发式关到以前的水平。我应该做的改变逐渐多了起来。 The C# compiler is kind enough to give you a "field is never assigned to" warning if you forget to initialize a readonly member which is private or internal, or if the class in which it is being declared is internal. But if the class is public, and the readonly member is public, protected or protected internal, then no warning for you!Does anyone know why?Sample code which demonstrates the conditions under which the warning is issued, and the conditions under which the warning is not issued: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. }}EDIT: For a moment you might think that the compiler refrains from issuing the warning in the case of public and protected members because it is reasonable to expect that derived classes might initialize the field. This theory does not hold any water for a number of reasons:An internal class may be subclassed, but the compiler does notrefrain from issuing the warning in that case.The compiler fails to issue the warning even in the case of a sealedclass, as Test3 in the sample code demonstrates.The warning makes sense for the sake of the integrity of the baseclass regardless of what a derived class may or may not do.A class is expressly prohibited by the language from initializing areadonly member of a base class. (Thanks, Jim Mischel.)EDIT2: If my memory serves me well, Java gives all the proper warnings in all cases, regardless of whether the uninitialized final member is public, protected or private, and regardless of whether the class containing it is public or visible only within its package. 解决方案 The short answer: this is an oversight in the compiler.The longer answer: the heuristic which determines what warnings to issue for members and locals that are declared and never used, or written and never read, or read and never written, does not take the read-only-ness of the field into consideration. As you correctly note, it could, and thereby issue warnings in more cases. We could say that a public readonly field that is not initialized in any ctor "will always have its default value" for example.I'll mention it to Neal in the new year and we'll see if we can improve those heuristics in Roslyn.Incidentally, there are a number of situations in which a warning of this sort could be issued (regardless of read-only-ness) but we do not do so. I am not in my office today so I don't have my list of all those situations handy, but suffice to say there are a lot of them. It was stuff like "the field is declared as public and is in a public nested class of an internal class". In that situation the field is effectively internal and we can do the warning, but sometimes we do not.One day many years ago I changed the heuristic so that every field that could be statically known to be unused produced a warning, and when that change made it into the internal version of the C# compiler that we use to compile the class libraries that are written in C#, all hell broke loose. Those guys always compile with "warnings as errors" turned on, and suddenly they started getting warnings on all kinds of fields that were deliberately initialized or used onl via reflection, and other dynamic techniques. I broke the build in a major way. Now, one might argue that hey, these guys should fix their code so that it suppresses the warning (and I did argue that) but ultimately it turned out to be easier to back the warning heuristic off to its previous level. I should have made the change more gradually. 这篇关于为什么我没有得到有关未初始化的只读域警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 07-30 18:37