This is a question raised by one of our team members in the programming process. This compilation error is easy to avoid, so I never thought about it carefully until I saw his Code Then I realized that this problem is not that simple.
Let's take a look at this Code:
Code Class Program
{
Static Void Main ( String [] ARGs)
{
Byte [] Buf = New Byte [ 1024 ];
T = New T ();
String Str = " 1234 " ;
Int N = 1234 ;
Int ? Nn = 1234 ;
Datetime dt = Datetime. now;
Object O = 1234 ;
Console. writeline ("Finish");
}
}
ClassT {}
How many variables have not been used in this code?
IfProgramThe answer should be that none of the variables have been used. However, the result provided by the compiler is a bit intuitive:
The variable "str" has been assigned a value, but its value has never been used.
The variable "N" has been assigned a value, but its value has never been used.
The variable "Nn" has been assigned a value, but its value has never been used.
The strange thing is that although all variables are declared in the same way, the compiler only considers that some of them have never been used. What's going on?
Let's analyze them one by one. First, let's look at the array. If the default value is used, the information provided by the compiler is different:
Byte [] Buf1 = Null ; // Warning
Byte [] Buf2 = New Byte [ 1024 ]; // No warning
This result seems to indicate that if the parameter value is null, the compiler does not really execute the value assignment and the variable will be treated as unused. The results of the Il check can also prove this statement: For the first line, the compiler does not generate any corresponding statement; for the second line, the newattr command is used to create an array.
For custom classes:
T T1 = Null ; // Warning
T T2 = New T (); // No warning
This result should be understandable (although understandable, I think it is not good. For the reason, see later ). Although we have not called any methods of the class, the class constructor may still execute some operations, so as long as a class is created, the compiler will regard it as used.
For the basic value type, its performance is different from the reference type. The Compiler does not regard the initial value as the usage of the variable:
Int N1 = 0 ; // Warning
Int N2 = 1234 ; // Warning
Int ? N3 = Null ; // Warning
Int ? N4 = 0 ; // Warning
Int ? N5 = 1234 ; // Warning
String is a reference type in implementation, but it is more similar to the value type, and the warning information and value type are the same.
For a slightly more complex value type, the result is a bit subtle:
Datetime dt1; // Warning
Datetime dt2 = New Datetime (); // Warning
Datetime dt3 = New Datetime ( 2009 , 1 , 1 ); // No warning
Datetime dt4 = Datetime. now; // No warning
Pay attention to this result. Although the default constructor of datetime and the constructor with parameters are the same constructor from the user perspective, they are different from the compiler perspective. The IL decompilation shows that if the default constructor is called, the compiler calls the initobj command, and the call ctor command is used to call the constructor with parameters. In addition, although the format of the value assignment code is identical from the programmer's perspective, the compiler uses different construction policies based on the assigned values, this is also contrary to intuition.
The final conclusion is a pity, that is, the C # compilation warning is not enough to give programmers enough protection, especially for Arrays:
Byte [] Buf = new byte [1, 1024];
If only such an array is constructed and not used, the compiler will not give the programmer any warning.
Another problem is worth considering. Declare a class without using any method, for example, just
T = new T ()
Is this a reasonable action? Should the compiler give a warning?
My personal opinion is that from the perspective of usage, this is unreasonable and should be avoided as much as possible. If the compiler finds this usage, it should give a warning. If necessary, you can use the Compilation instruction or attribute method to specifically declare it to avoid warning information. However, the C # compiler does not give a warning, which I do not agree. Of course, I also hope you can come up with your own ideas.