Csharp/CSharp Tutorial/Data Type/Data Type Cast

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Automatic conversion from long to double

<source lang="csharp">using System;

class Example {

 public static void Main() {    
   long L; 
   double D; 
  
   L = 100123285L; 
   D = L; 
  
   Console.WriteLine("L and D: " + L + " " + D); 
 }    

}</source>

L and D: 100123285 100123285

Automatic Conversions

An automatic type conversion will take place if

  1. The two types are compatible.
  2. The destination type is larger than the source type.

When these two conditions are met, a widening conversion takes place.

For example, the int type is always large enough to hold all valid byte values

Both int and byte are integer types, so an automatic conversion can be applied.

2.49.Data Type Cast 2.49.1. <A href="/Tutorial/CSharp/0040__Data-Type/TypeConversioninExpressions.htm">Type Conversion in Expressions</a> 2.49.2. Automatic Conversions 2.49.3. <A href="/Tutorial/CSharp/0040__Data-Type/Theuseofthecastoperatorhowinformationlosscanoccurwhenexplicitlyconvertingavariableofonetypetoanother.htm">The use of the cast operator: how information loss can occur when explicitly converting a variable of one type to another</a> 2.49.4. <A href="/Tutorial/CSharp/0040__Data-Type/Automaticconversionfromlongtodouble.htm">Automatic conversion from long to double</a> 2.49.5. <A href="/Tutorial/CSharp/0040__Data-Type/Castanintintoadouble.htm">Cast an int into a double</a> 2.49.6. <A href="/Tutorial/CSharp/0040__Data-Type/Castanintintoabytenodatalost.htm">Cast an int into a byte, no data lost</a> 2.49.7. <A href="/Tutorial/CSharp/0040__Data-Type/Castanintintoabytedatalost.htm">Cast an int into a byte, data lost</a> 2.49.8. <A href="/Tutorial/CSharp/0040__Data-Type/Castauintintoashortnodatalost.htm">Cast a uint into a short, no data lost</a> 2.49.9. <A href="/Tutorial/CSharp/0040__Data-Type/Castauintintoashortdatalost.htm">Cast a uint into a short, data lost</a> 2.49.10. <A href="/Tutorial/CSharp/0040__Data-Type/Castalongintoauintnodatalost.htm">Cast a long into a uint, no data lost</a> 2.49.11. <A href="/Tutorial/CSharp/0040__Data-Type/castalongintoauintdatalost.htm">cast a long into a uint, data lost</a> 2.49.12. <A href="/Tutorial/CSharp/0040__Data-Type/Castanintintoachar.htm">Cast an int into a char</a> 2.49.13. <A href="/Tutorial/CSharp/0040__Data-Type/Castbytebackforbytecalculation.htm">Cast byte back for byte calculation</a> 2.49.14. <A href="/Tutorial/CSharp/0040__Data-Type/Usingcastsinanexpression.htm">Using casts in an expression.</a> 2.49.15. <A href="/Tutorial/CSharp/0040__Data-Type/Conversionsofnumerictypescheckedanduncheckedconversions.htm">Conversions of numeric types: checked and unchecked conversions</a> 2.49.16. <A href="/Tutorial/CSharp/0040__Data-Type/Conversionsofnumerictypescheckedconversionsblock.htm">Conversions of numeric types: checked conversions block</a> 2.49.17. <A href="/Tutorial/CSharp/0040__Data-Type/Usingcheckedandunchecked.htm">Using checked and unchecked.</a> 2.49.18. <A href="/Tutorial/CSharp/0040__Data-Type/Usingcheckedanduncheckedwithstatementblocks.htm">Using checked and unchecked with statement blocks.</a> 2.49.19. <A href="/Tutorial/CSharp/0040__Data-Type/Mostsignificantbitslost.htm">Most significant bits lost</a> 2.49.20. <A href="/Tutorial/CSharp/0040__Data-Type/RaisestheOverflowExceptionexception.htm">Raises the OverflowException exception</a> 2.49.21. <A href="/Tutorial/CSharp/0040__Data-Type/GetTypeCodeaftercasting.htm">Get Type Code after casting</a> 2.49.22. <A href="/Tutorial/CSharp/0040__Data-Type/NarrowWithConvert.htm">Narrow With Convert</a> 2.49.23. <A href="/Tutorial/CSharp/0040__Data-Type/Narrowinginttobyte.htm">Narrowing int to byte</a> 2.49.24. <A href="/Tutorial/CSharp/0040__Data-Type/OverflowCheckfordatatypeconverting.htm">Overflow Check for data type converting</a> 2.49.25. <A href="/Tutorial/CSharp/0040__Data-Type/NotUsingtheCastOperatorforanImplicitCast.htm">Not Using the Cast Operator for an Implicit Cast</a> 2.49.26. <A href="/Tutorial/CSharp/0040__Data-Type/UsingtheCastOperatorforanImplicitCast.htm">Using the Cast Operator for an Implicit Cast</a> 2.49.27. <A href="/Tutorial/CSharp/0040__Data-Type/DataConversion.htm">Data Conversion</a> 2.49.28. <A href="/Tutorial/CSharp/0040__Data-Type/implicittypeconversionssupportedinC.htm">implicit type conversions supported in C#.</a>

cast a long into a uint, data lost

<source lang="csharp">using System;

class Example {

 public static void Main() {    
   uint u; 
   long l; 

   // cast a long into a uint, data lost 
   l = -12; 
   u = (uint) l; 
   Console.WriteLine("u after assigning -12: " + u + 
                     " -- data lost.");  
 }

}</source>

u after assigning -12: 4294967284 -- data lost.

Cast a long into a uint, no data lost

<source lang="csharp">using System;

class Example {

 public static void Main() {    
   uint u; 
   long l; 

   l = 64000; 
   u = (uint) l; 
   Console.WriteLine("u after assigning 64000: " + u + 
                     " -- no data lost.");  

 }

}</source>

u after assigning 64000: 64000 -- no data lost.

Cast an int into a byte, data lost

<source lang="csharp">using System;

class Example {

 public static void Main() {    
   byte b; 
   int i; 
   
   i = 257; 
   b = (byte) i;  
   Console.WriteLine("b after assigning 257: " + b + 
                     " -- data lost."); 

 }

}</source>

b after assigning 257: 1 -- data lost.

Cast an int into a byte, no data lost

<source lang="csharp">using System;

class Example {

 public static void Main() {    
   byte b; 
   int i; 
   
   i = 255; 
   b = (byte) i;  
   Console.WriteLine("b after assigning 255: " + b + 
                     " -- no data lost."); 
 }

}</source>

b after assigning 255: 255 -- no data lost.

Cast an int into a char

<source lang="csharp">using System;

class Example {

 public static void Main() {    
   byte b; 
   char ch; 
   b = 88; // ASCII code for X 
   ch = (char) b; 
   Console.WriteLine("ch after assigning 88: " + ch);  
 }

}</source>

ch after assigning 88: X

Cast an int into a double

<source lang="csharp">using System;

class Example {

 public static void Main() {    
   double x, y; 
   int i; 
   x = 10.0; 
   y = 3.0; 

   i = (int) (x / y); // cast double to int, fractional component lost 
   Console.WriteLine("Integer outcome of x / y: " + i); 
   Console.WriteLine(); 
    
 }    

}</source>

Integer outcome of x / y: 3

Cast a uint into a short, data lost

<source lang="csharp">using System;

class Example {

 public static void Main() {    
   uint u; 
   short s; 

   u = 64000; 
   s = (short) u; 
   Console.WriteLine("s after assigning 64000: " + s + 
                     " -- data lost.");  
 }

}</source>

s after assigning 64000: -1536 -- data lost.

Cast a uint into a short, no data lost

<source lang="csharp">using System;

class Example {

 public static void Main() {    
   uint u; 
   short s; 
   
   u = 32000; 
   s = (short) u; 
   Console.WriteLine("s after assigning 32000: " + s + 
                     " -- no data lost.");  
 }

}</source>

s after assigning 32000: 32000 -- no data lost.

Cast byte back for byte calculation

<source lang="csharp">using System;

class Example {

 public static void Main() {     
   byte b;  
   
   b = 10;  
   b = (byte) (b * b); // cast needed!
 
   Console.WriteLine("b: "+ b);  
 }     

}</source>

b: 100

Conversions of numeric types: checked and unchecked conversions

<source lang="csharp">using System; class MainClass {

   public static void Main()
   {
       uint value1 = 999;
       byte value2;
       
       value2 = unchecked((byte) value1);    // never checked
       value2 = (byte) value1;            // checked if /checked
       value2 = checked((byte) value1);        // always checked
   }

}</source>

Unhandled Exception: System.OverflowException: Arithmetic operation resulted in an overflow.
   at MainClass.Main()

Conversions of numeric types: checked conversions block

<source lang="csharp">using System; class MainClass {

   public static void Main()
   {
       checked
       {
           uint value1 = 312;
           byte value2 = (byte) value1;
           Console.WriteLine("Value: {0}", value2);
       }
   }

}</source>

Unhandled Exception: System.OverflowException: Arithmetic operation resulted in an overflow.
   at MainClass.Main()

Data Conversion

<source lang="csharp">using System; class Class1 {

   static void Main(string[] args)
   {
       int x, m, b;
       double xd, md, bd;
       m = 2;
       md = 2.1;
       x = 3;
       xd = 4;
       b = 5;
       bd = 6.5;
       Console.WriteLine("int version of CalcY returns: {0}", IntFindY(m, x, b));
       Console.WriteLine("double version of FindY returns: {0}", DoubleFindY(md, xd, bd));
       Console.WriteLine("int version using doubles returns: {0}", IntFindY((int)md, (int)xd, (int)bd));
       Console.WriteLine("double version using ints returns: {0}", DoubleFindY(m, x, b));
   }
   static int IntFindY(int m, int x, int b)
   {
       return (m * x) + b;
   }
   static double DoubleFindY(double m, double x, double b)
   {
       return (m * x) + b;
   }

}</source>

Get Type Code after casting

<source lang="csharp">using System; using System.Globalization; class MainClass {

 static void Main(string[] args)
 {      
   // Get the type code of C# int.
   int theInt = 65;
   Console.WriteLine("Type code of int is: {0}", theInt.GetTypeCode());
   Console.WriteLine("Casting System.Int32 to System.Char");
   char theChar = (char)theInt;  
   Console.WriteLine("Type code int converted to char is: {0}", theChar.GetTypeCode());
   Console.WriteLine("Value of converted char: {0}", theChar);
   
 }

}</source>

Type code of int is: Int32
Casting System.Int32 to System.Char
Type code int converted to char is: Char
Value of converted char: A

implicit type conversions supported in C#.

<source lang="csharp">From To sbyte short, int, long, float, double, decimal byte short, ushort, int, uint, long, ulong, float, double, decimal short int, long, float, double, decimal ushort int, uint, long, ulong, float, double, decimal int long, float, double, decimal uint long, ulong, float, double, decimal long, ulong float, double, decimal float double char ushort, int, uint, long, ulong, float, double, decimal</source>

Most significant bits lost

<source lang="csharp">using System; class MainClass {

  static void Main(string[] args)
  {
     ushort sh = 2000;
     byte sb;
     sb = unchecked((byte)sh);            
     Console.WriteLine("sb: {0}", sb);
  }

}</source>

sb: 208

Narrowing int to byte

<source lang="csharp">using System; using System.Collections.Generic; using System.Text;

 class Program
 {
   static void Main(string[] args)
   {
     byte myByte = 0;
     int myInt = 200;
     myByte = (byte)myInt;
     Console.WriteLine("Value of myByte: {0}", myByte);
   }
 }</source>

Narrow With Convert

<source lang="csharp">using System; using System.Collections.Generic; using System.Text;

 class Program
 {
   static void Main(string[] args)
   {
     byte myByte = 0;
     int myInt = 200;
     myByte = Convert.ToByte(myInt);
     Console.WriteLine("Value of myByte: {0}", myByte);
   }
 }</source>

Not Using the Cast Operator for an Implicit Cast

<source lang="csharp">class MainClass {

 static void Main()
 {
   int intNumber = 31416;
   long longNumber = intNumber;
 }

}</source>

Overflow Check for data type converting

<source lang="csharp">using System; using System.Collections.Generic; using System.Linq; using System.Text;

   class Program
   {
       static void Main(string[] args)
       {
           byte destinationVar;
           short sourceVar = 281;
           destinationVar = checked((byte)sourceVar);
           Console.WriteLine("sourceVar val: {0}", sourceVar);
           Console.WriteLine("destinationVar val: {0}", destinationVar);
       }
   }</source>

Raises the OverflowException exception

<source lang="csharp">using System; class MainClass {

  static void Main(string[] args)
  {
     ushort sh = 2000;
     byte sb;
     sb = checked((byte)sh);              
     Console.WriteLine("sb: {0}", sb);
  }

}</source>

Unhandled Exception: System.OverflowException: Arithmetic operation resulted in an overflow.
   at MainClass.Main(String[] args)

The use of the cast operator: how information loss can occur when explicitly converting a variable of one type to another

<source lang="csharp">class MainClass {

 public static void Main()
 {
   short myShort = 17000;
   System.Console.WriteLine("myShort = " + myShort);
   int myInt = myShort;
   System.Console.WriteLine("myInt = " + myInt);
   myShort = (short) (myInt * 2);
   System.Console.WriteLine("myShort = " + myShort);
 }

}</source>

myShort = 17000
myInt = 17000
myShort = -31536

Type Conversion in Expressions

C#"s type promotion rules. Here is the algorithm that they define for binary operations:

  1. IF one operand is a decimal, THEN the other operand is promoted to decimal (unless it is of type float or double, in which case an error results).
  2. ELSE IF one operand is a double, the second is promoted to double.
  3. ELSE IF one operand is a float, the second is promoted to float.
  4. ELSE IF one operand is a ulong, the second is promoted to ulong (unless it is of type sbyte, short, int, or long, in which case an error results).
  5. ELSE IF one operand is a long, the second is promoted to long.
  6. ELSE IF one operand is a uint and the second is of type sbyte, short, or int, both are promoted to long.
  7. ELSE IF one operand is a uint, the second is promoted to uint.
  8. ELSE both operands are promoted to int.

Quote from Book: C# The Complete Reference Paperback: 933 pages Publisher: Osborne/McGraw-Hill (March 8, 2002) Language: English ISBN-10: 0072134852 ISBN-13: 978-0072134858

A cast has this general form:


<source lang="csharp">(target-type) expression</source>

When a cast involves a narrowing conversion, information might be lost.

Using casts in an expression.

<source lang="csharp">using System;

class Example {

 public static void Main() {     
   double n;  
 
    for(n = 1.0; n <= 10; n++) {  
      Console.WriteLine("The square root of {0} is {1}",  
                        n, Math.Sqrt(n));  
 
      Console.WriteLine("Whole number part: {0}" ,   
                        (int) Math.Sqrt(n));  
  
      Console.WriteLine("Fractional part: {0}",   
                        Math.Sqrt(n) - (int) Math.Sqrt(n) );  
      Console.WriteLine(); 
   }  
 }     

}</source>

The square root of 1 is 1
Whole number part: 1
Fractional part: 0
The square root of 2 is 1.4142135623731
Whole number part: 1
Fractional part: 0.414213562373095
The square root of 3 is 1.73205080756888
Whole number part: 1
Fractional part: 0.732050807568877
The square root of 4 is 2
Whole number part: 2
Fractional part: 0
The square root of 5 is 2.23606797749979
Whole number part: 2
Fractional part: 0.23606797749979
The square root of 6 is 2.44948974278318
Whole number part: 2
Fractional part: 0.449489742783178
The square root of 7 is 2.64575131106459
Whole number part: 2
Fractional part: 0.645751311064591
The square root of 8 is 2.82842712474619
Whole number part: 2
Fractional part: 0.82842712474619
The square root of 9 is 3
Whole number part: 3
Fractional part: 0
The square root of 10 is 3.16227766016838
Whole number part: 3
Fractional part: 0.16227766016838

Using checked and unchecked.

<source lang="csharp">using System;

class MainClass {

 public static void Main() {  
   byte a, b; 
   byte result; 

   a = 127; 
   b = 127; 
 
   try {  
     result = unchecked((byte)(a * b)); 
     Console.WriteLine("Unchecked result: " + result); 

     result = checked((byte)(a * b)); // this causes exception 
     Console.WriteLine("Checked result: " + result); // won"t execute 
   }  
   catch (OverflowException exc) {  
     // catch the exception  
     Console.WriteLine(exc); 
   }  
 }  

}</source>

Unchecked result: 1
System.OverflowException: Arithmetic operation resulted in an overflow.
   at MainClass.Main()

Using checked and unchecked with statement blocks.

<source lang="csharp">using System;

class MainClass {

 public static void Main() {  
   byte a, b; 
   byte result; 

   a = 127; 
   b = 127; 
 
   try {  
     unchecked { 
       result = unchecked((byte)(a * b)); 
       Console.WriteLine("Unchecked result: " + result); 

       result = unchecked((byte)(a * b)); 
       Console.WriteLine("Unchecked result: " + result); 
     } 

     checked { 
       result = checked((byte)(a * b)); 
       Console.WriteLine("Checked result: " + result); 

       result = checked((byte)(a * b)); 
       Console.WriteLine("Checked result: " + result); 
     } 
   }  
   catch (OverflowException exc) {  
     // catch the exception  
     Console.WriteLine(exc); 
   }  
 }  

}</source>

Unchecked result: 1
Unchecked result: 1
System.OverflowException: Arithmetic operation resulted in an overflow.
   at MainClass.Main()

Using the Cast Operator for an Implicit Cast

<source lang="csharp">class MainClass {

 static void Main()
 {
   int intNumber = 31416;
   long longNumber = (long) intNumber;
 }

}</source>