- The data types supported directly by the compiler become primitive types (primitive type). Primitive types map directly to types that exist in the Framework class library (FCL).
int a = 0; // Most convenient syntax
System.Int32 a = 0; // Convenient syntax
int a = new int(); // Inconvenient syntax
System.Int32 a = new System.Int32(); // Most inconvenient syntax
-
//3rd example
-
Span class= "Typ" >binaryreader br = new binaryreader (...);
-
float val = br readsingle (); //OK, but feels unnatural
-
single val = br Span class= "pun". readsingle (); //OK and feels good
- Different types, and there is no inheritance relationship, normally it cannot be converted directly. However, Int32 can be implicitly converted to Int64. Because the C # compiler is very familiar with primitive types, it applies its own special rules when compiling code. Example:
Int32 i = 5; // Implicit cast from Int32 to Int32
Int64 l = i; // Implicit cast from Int32 to Int64
Single s = i; // Implicit cast from Int32 to Single
Byte b = (Byte) i; // Explicit cast from Int32 to Byte
Int16 v = (Int16) s; // Explicit cast from Single to Int16
- C # allows implicit conversions only if the type is safe ( No data loss occurs ).
- Different compilers may generate different code to handle transformations. When converting a single of 6.8 to Int32, some compilers may truncate (rounded down), while others may be converted to 7 (rounding up). C # always truncates results (rounded down)
- The base type can be written as a literal value (literal), which is literally an instance of the type itself. So you can use the instance method for it:
Console.WriteLine(123.ToString() + 456.ToString()); // "123456"
- If the expression consists of literal values, the compiler can complete the evaluation of an expression at compile time .
Boolean found = false; // Generated code sets found to 0
Int32 x = 100 + 20 + 3; // Generated code sets x to 123
String s = "a " + "bc"; // Generated code sets s to "a bc"
Checked and unchecked primitive type operations
- Many arithmetic operations performed by primitive types can cause overflow:
-
Byte b = 100 ;
-
b = ( byte b + 200 );
- When performing the above operation, the first step is to expand the operand to 32 bits (or 64 bits), and the result must be converted to Byte before the variable b is stored back.
- Different languages process the removal in different ways. C and C + + do not treat overflows as actions, allow value rollback (wrap), and VB always treats overflow as an error.
- The CLR provides special IL directives that allow the compiler to choose the behavior it deems most appropriate. The addition, subtraction, multiplication, and addition of the CLR provide the relevant directives: ADD/ADD.OVF,SUB/SUB.OVF,MUL/MUL.OVF,CONV/CONV.OVF. With. OVF throws an System.OverflowException exception when an exception is thrown, without an. OVF means that overflow checking is not performed.
- C # turns off overflow checking by default.
- The C # compiler uses the/checked+ compile switch. The code generated when it is turned on is slightly slower to execute because the calculation results need to be checked.
- C # provides checked and unchecked operators to control overflow checking of code-specified areas.
Uint32 invalid = unchecked((Uint32) (-1)); // OK
Byte b = 100;
b = checked((Byte) (b + 200)); // OverflowException is thrown
b = (Byte) checked(b + 200); // b contains 44; no OverflowException
- In the last example, B + 200 will first be converted to a 32-bit value, so it will not be detected as overflow.
- C # supports checked and unchecked statements, and expressions within their statement blocks are checked for/without overflow.
-
checked
-
{ //Start of checked block
-
byte b = 100 ;
-
b += //This expression was checked for overflow.
-
} //End of checked block
- The only effect of the checked operator and the checked statement is to determine which version of the add, subtract, multiply, divide, and data conversion Il directives are generated, so calling the method in the checked operator and the statement will not have any effect on the method.
checked
{
// Assume SomeMethod tries to load 400 into a Byte.
SomeMethod(400);
// SomeMethod might or might not throw an OverflowException.
// It would if SomeMethod were compiled with checked instructions.
}
- Some suggestions:
- Try to use a signed number (such as Int32,int64) instead of an unsigned number, which allows the compiler to detect more overflow/underflow errors. Many class libraries (the length property of Array and String) are hard-coded to return signed values, which reduces the type conversion. The unsigned number is not CLS compliant (Common Language specification).
- When writing code, you do not want the overflow part to be placed in the checked block, while capturing the OverflowException and processing accordingly.
- When writing code, the code that is allowed to overflow appears in the unchecked block, such as calculating checksums.
- For code that does not use checked and unchecked, it is assumed that you want to generate an exception when overflow, and that the overflow is a bug.
- When developing the program, turn on the compile switch/checked+, detect the exception, and apply the compiler's/checked-at publish time to ensure the efficiency of the operation.
- If efficiency permits, turn on/checked+ to prevent data corruption.
- System.Decimal is considered a primitive type by many languages (such as C # and VB), but the CLR does not treat it as a primitive type. The CLR does not handle the IL directive for Decimal. The compiler generates code to invoke the members of the decimal and to perform the operations through those members, which means that the decimal value is processed slower than the value of the CLR primitive type.
- Because the CLR does not handle the IL directive for Decimal, checked and unchecked are not valid, and if an overflow occurs, it is bound to throw OverflowException.
Add
- The following operations are affected by overflow checking:
- An expression uses the following predefined operators on an integral type:
++--(one yuan) +-*/
- Explicit numeric conversions between integral types.
- Checked unchecked IL test:
static void CheckUncheckTest()
{
byte a = 100;
a = (byte)( a + 200 );
a = 100;
checked
{
a = (byte)( a + 200 ); //抛出异常
}
}
- Vs to checked compilation option on Turn off setting: Properties----Advanced---check operation overflow/underflow
5.1 Primitive types for programming languages