Csharp/C Sharp/Data Types/Casting Conversions

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

An example that uses an implicit conversion operator

/*
C#: The Complete Reference 
by Herbert Schildt 
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/

// An example that uses an implicit conversion operator. 
 
using System; 
 
// A three-dimensional coordinate class. 
class ThreeD { 
  int x, y, z; // 3-D coordinates   
 
  public ThreeD() { x = y = z = 0; } 
  public ThreeD(int i, int j, int k) { x = i; y = j; z = k; } 
 
  // Overload binary +. 
  public static ThreeD operator +(ThreeD op1, ThreeD op2) 
  { 
    ThreeD result = new ThreeD(); 
 
    result.x = op1.x + op2.x;  
    result.y = op1.y + op2.y;  
    result.z = op1.z + op2.z;  
 
    return result; 
  } 
 
  // An implicit conversion from ThreeD to int. 
  public static implicit operator int(ThreeD op1) 
  { 
    return op1.x * op1.y * op1.z; 
  } 
   
  // Show X, Y, Z coordinates. 
  public void show() 
  { 
    Console.WriteLine(x + ", " + y + ", " + z); 
  } 
} 
 
public class ThreeDDemo5 { 
  public static void Main() { 
    ThreeD a = new ThreeD(1, 2, 3); 
    ThreeD b = new ThreeD(10, 10, 10); 
    ThreeD c = new ThreeD(); 
    int i; 
 
    Console.Write("Here is a: "); 
    a.show(); 
    Console.WriteLine(); 
    Console.Write("Here is b: "); 
    b.show(); 
    Console.WriteLine(); 
 
    c = a + b; // add a and b together 
    Console.Write("Result of a + b: "); 
    c.show(); 
    Console.WriteLine(); 
 
    i = a; // convert to int 
    Console.WriteLine("Result of i = a: " + i); 
    Console.WriteLine(); 
 
    i = a * 2 - b; // convert to int 
    Console.WriteLine("result of a * 2 - b: " + i); 
  } 
}


Casting int float and byte

/*
 * C# Programmers Pocket Consultant
 * Author: Gregory S. MacBeth
 * Email: gmacbeth@comporium.net
 * Create Date: June 27, 2003
 * Last Modified Date:
 * Version: 1
 */
using System;
namespace Client.Chapter_1___Common_Type_System
{
  public class Casting
  {
    static void Main(string[] args)
    {
      int MyInt = 12345;
      long MyLong = MyInt;  
      short MyShort = (short)MyInt;
    }
  }
}


Classes and Pre and Post Conversions

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 24 - User-Defined Conversions\Classes and Pre and Post Conversions
// copyright 2000 Eric Gunnerson
using System;
using System.Text;
public class ClassesandPreandPostConversions
{
    public static void Main()
    {
        // implicit conversion section
        RomanNumeralAlternate    roman;
        roman = new RomanNumeralAlternate(55);
        
        BinaryNumeral binary = roman;
        // explicit conversion section
        BinaryNumeral binary2 = new BinaryNumeral(1500);
        RomanNumeralAlternate roman2;
        
        roman2 = (RomanNumeralAlternate) binary2;
    }
}
class RomanNumeral
{
    public RomanNumeral(short value) 
    {
        if (value > 5000)
        throw(new ArgumentOutOfRangeException());
        
        this.value = value;
    }
    public static explicit operator RomanNumeral(
    short value) 
    {
        RomanNumeral    retval;
        retval = new RomanNumeral(value);
        return(retval);
    }
    
    public static implicit operator short(
    RomanNumeral roman)
    {
        return(roman.value);
    }
    
    static string NumberString(
    ref int value, int magnitude, char letter)
    {
        StringBuilder    numberString = new StringBuilder();
        
        while (value >= magnitude)
        {
            value -= magnitude;
            numberString.Append(letter);
        }
        return(numberString.ToString());
    }
    
    public static implicit operator string(
    RomanNumeral roman)
    {
        int        temp = roman.value;
        
        StringBuilder retval = new StringBuilder();
        
        retval.Append(RomanNumeral.NumberString(ref temp, 1000, "M"));
        retval.Append(RomanNumeral.NumberString(ref temp, 500, "D"));
        retval.Append(RomanNumeral.NumberString(ref temp, 100, "C"));
        retval.Append(RomanNumeral.NumberString(ref temp, 50, "L"));
        retval.Append(RomanNumeral.NumberString(ref temp, 10, "X"));
        retval.Append(RomanNumeral.NumberString(ref temp, 5, "V"));
        retval.Append(RomanNumeral.NumberString(ref temp, 1, "I"));
        
        return(retval.ToString());
    }
    public static implicit operator BinaryNumeral(RomanNumeral roman)
    {
        return(new BinaryNumeral((short) roman));
    }
    
    public static explicit operator RomanNumeral(
    BinaryNumeral binary)
    {
        return(new RomanNumeral((short)(int) binary));
    }
    
    private short value;
}
class BinaryNumeral
{
    public BinaryNumeral(int value) 
    {
        this.value = value;
    }
    public static implicit operator BinaryNumeral(
    int value) 
    {
        BinaryNumeral    retval = new BinaryNumeral(value);
        return(retval);
    }
    
    public static implicit operator int(
    BinaryNumeral binary)
    {
        return(binary.value);
    }
    
    public static implicit operator string(
    BinaryNumeral binary)
    {
        StringBuilder    retval = new StringBuilder();
        
        return(retval.ToString());
    }
    
    private int value;
}
class RomanNumeralAlternate : RomanNumeral
{
    public RomanNumeralAlternate(short value): base(value)
    {
    }
    
    public static implicit operator string(
    RomanNumeralAlternate roman)
    {
        return("NYI");
    }
}


Conversion Lookup

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 24 - User-Defined Conversions\How It Works\Conversion Lookup
// copyright 2000 Eric Gunnerson
public class ConversionLookup
{
    public static void Main()
    {
        S myS = new S();
        TBase tb = (TBase) myS;
    }
}
public class S
{
    public static implicit operator T(S s) 
    { 
        // conversion here
        return(new T());
    }
}
public class TBase
{
}
public class T: TBase
{
    
}


Conversions: Numeric Types

public class NumericTypesConversion
{
    public static void Main()
    {
        // all implicit
        sbyte v = 55;
        short v2 = v;
        int v3 = v2;
        long v4 = v3;
        
        // explicit to "smaller" types
        v3 = (int) v4;
        v2 = (short) v3;
        v = (sbyte) v2;
    }
}


Conversions:Numeric Types:Checked Conversions

using System;
public class UNCheckedConversions
{
    public static void Main()
    {
        uint value1 = 312;
        byte value2;
        
        value2 = unchecked((byte) value1);    // never checked
        value2 = (byte) value1;               // checked if /checked
        value2 = checked((byte) value1);      // always checked
    }
}


Conversions:Numeric Types:Conversions and Member Lookup

using System;
class Conv
{
    public static void Process(sbyte value)
    {
        Console.WriteLine("sbyte {0}", value);
    }
    public static void Process(short value)
    {
        Console.WriteLine("short {0}", value);
    }
    public static void Process(int value)
    {
        Console.WriteLine("int {0}", value);
    }
}
public class ConversionsandMemberLookup
{
    public static void Main()
    {
        int    value1 = 2;
        sbyte    value2 = 1;
        Conv.Process(value1);
        Conv.Process(value2);
    }
}


Conversions:Numeric Types:Explicit Numeric Conversions

using System;
public class ExplicitNumericConversions
{
    public static void Main()
    {
        uint value1 = 312;
        byte value2 = (byte) value1;
        Console.WriteLine("Value2: {0}", value2);
    }
}


Conversions of Classes (Reference Types)\To an Interface the Object Might Implement

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 15 - Conversions\Conversions of Classes (Reference Types)\To an Interface 
// the Object Might Implement
// copyright 2000 Eric Gunnerson
using System;
interface IDebugDump
{
    string DumpObject();
}
class Simple
{
    public Simple(int value)
    {
        this.value = value;
    }
    public override string ToString()
    {
        return(value.ToString());
    }
    int value;
}
class Complicated: IDebugDump
{
    public Complicated(string name)
    {
        this.name = name;
    }
    public override string ToString()
    {
        return(name);
    }
    string IDebugDump.DumpObject()
    {
        return(String.Format(
        "{0}\nLatency: {1}\nRequests: {2}\nFailures: {3}\n",
    new object[] {name,    latency, requestCount, failedCount} ));
    }
    string name;
    int latency = 0;
    int requestCount = 0;
    int failedCount = 0;
}
public class ToanInterfacetheObjectMightImplement
{
    public static void DoConsoleDump(params object[] arr)
    {
        foreach (object o in arr)
        {
            IDebugDump dumper = o as IDebugDump;
            if (dumper != null)
            Console.WriteLine("{0}", dumper.DumpObject());
            else
            Console.WriteLine("{0}", o);
        }
    }
    public static void Main()
    {
        Simple s = new Simple(13);
        Complicated c = new Complicated("Tracking Test");
        DoConsoleDump(s, c);
    }
}


Conversions of Classes (Reference Types):To the Base Class of an Object

using System;
class Base
{
    public virtual void WhoAmI()
    {
        Console.WriteLine("Base");
    }
}
class Derived: Base
{
    public override void WhoAmI()
    {
        Console.WriteLine("Derived");
    }
}
public class TotheBaseClassofanObject {
    public static void Main()
    {
        Derived d = new Derived();
        Base b = d;
        
        b.WhoAmI();
        Derived d2 = (Derived) b;
        
        object o = d;
        Derived d3 = (Derived) o;
    }
}


illustrates casting objects

/*
Mastering Visual C# .NET
by Jason Price, Mike Gunderloy
Publisher: Sybex;
ISBN: 0782129110
*/
/*
  Example7_11.cs illustrates casting objects
*/
using System;

// declare the MotorVehicle class (the base class)
class MotorVehicle
{
  public string model;
  public MotorVehicle(string model)
  {
    this.model = model;
  }
  public void Start()
  {
    Console.WriteLine(model + " started");
  }
}

// declare the Car class
class Car : MotorVehicle
{
  public bool convertible;
  public Car(string model, bool convertible) :
  base(model)
  {
    this.convertible = convertible;
  }
}

// declare the Motorcycle class
class Motorcycle : MotorVehicle
{
  public bool sidecar;
  // define a constructor
  public Motorcycle(string model, bool sidecar) :
  base(model)
  {
    this.sidecar = sidecar;
  }
  public void PullWheelie()
  {
    Console.WriteLine(model + " pulling a wheelie!");
  }
}

public class Example7_11
{
  public static void Main()
  {
    // create a Car object
    Car myCar = new Car("MR2", true);
    // cast myCar to MotorVehicle (upcast)
    MotorVehicle myMotorVehicle = (MotorVehicle) myCar;
    // myMotorVehicle only has a model field and Start() method
    // (no convertible field)
    Console.WriteLine("myMotorVehicle.model = " + myMotorVehicle.model);
    myMotorVehicle.Start();
    // Console.WriteLine("myMotorVehicle.convertible = " +
    //   myMotorVehicle.convertible);
    // create a Motorcycle object
    Motorcycle myMotorcycle = new Motorcycle("V-Rod", true);
    // cast myMotorcycle to MotorVehicle (upcast)
    MotorVehicle myMotorVehicle2 = (MotorVehicle) myMotorcycle;
    // myMotorVehicle only has a model field and Start() method
    // (no sidecar field or PullWheelie() method)
    Console.WriteLine("myMotorVehicle2.model = " + myMotorVehicle2.model);
    myMotorVehicle2.Start();
    // Console.WriteLine("myMotorVehicle2.sidecar = " +
    //   myMotorVehicle2.sidecar);
    // myMotorVehicle2.PullWheelie();
    // cast myMotorVehicle2 to Motorcycle (downcast)
    Motorcycle myMotorcycle2 = (Motorcycle) myMotorVehicle2;
    // myMotorCycle2 has access to all members of the Motorcycle class
    Console.WriteLine("myMotorcycle2.model = " + myMotorcycle2.model);
    Console.WriteLine("myMotorcycle2.sidecar = " + myMotorcycle2.sidecar);
    myMotorcycle2.Start();
    myMotorcycle2.PullWheelie();
    // cannot cast a Motorcyle object to the Car class because
    // their classes are not compatible
    // Car myCar2 = (Car) myMotorVehicle2;
  }
}


InvalidCastException

using System;
   
class MainClass
{
    public static void Main()
    {
        try
        {
            MainClass       MyObject = new MainClass();
            IFormattable    Formattable;
   
            Formattable = (IFormattable)MyObject;
        }
        catch(InvalidCastException)
        {
            Console.WriteLine("MyObject does not implement the IFormattable interface.");
   
        }
    }
}


Numeric Types: Checked Conversions

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


The use of the cast operator

/*
Mastering Visual C# .NET
by Jason Price, Mike Gunderloy
Publisher: Sybex;
ISBN: 0782129110
*/
/*
  Example2_3.cs shows the use of the cast operator,
  and how information loss can occur when explicitly
  converting a variable of one type to another
*/
public class Example2_3
{
  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);
  }
}


Use an explicit conversion

/*
C#: The Complete Reference 
by Herbert Schildt 
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/

// Use an explicit conversion. 
 
using System; 
 
// A three-dimensional coordinate class. 
class ThreeD { 
  int x, y, z; // 3-D coordinates   
 
  public ThreeD() { x = y = z = 0; } 
  public ThreeD(int i, int j, int k) { x = i; y = j; z = k; } 
 
  // Overload binary +. 
  public static ThreeD operator +(ThreeD op1, ThreeD op2) 
  { 
    ThreeD result = new ThreeD(); 
 
    result.x = op1.x + op2.x;  
    result.y = op1.y + op2.y;  
    result.z = op1.z + op2.z;  
 
    return result; 
  } 
 
  // This is now explicit. 
  public static explicit operator int(ThreeD op1) 
  { 
    return op1.x * op1.y * op1.z; 
  } 
   
  // Show X, Y, Z coordinates. 
  public void show() 
  { 
    Console.WriteLine(x + ", " + y + ", " + z); 
  } 
} 
 
public class ThreeDDemo7 { 
  public static void Main() { 
    ThreeD a = new ThreeD(1, 2, 3); 
    ThreeD b = new ThreeD(10, 10, 10); 
    ThreeD c = new ThreeD(); 
    int i; 
 
    Console.Write("Here is a: "); 
    a.show(); 
    Console.WriteLine(); 
    Console.Write("Here is b: "); 
    b.show(); 
    Console.WriteLine(); 
 
    c = a + b; // add a and b together 
    Console.Write("Result of a + b: "); 
    c.show(); 
    Console.WriteLine(); 
 
    i = (int) a; // explicitly convert to int -- cast required 
    Console.WriteLine("Result of i = a: " + i); 
    Console.WriteLine(); 
 
    i = (int)a * 2 - (int)b; // casts required 
    Console.WriteLine("result of a * 2 - b: " + i); 
 
  } 
}


User-Defined Conversions:A Simple Example

/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress  L.P.
ISBN: 1-893115-62-3
*/
// 24 - User-Defined Conversions\A Simple Example
// copyright 2000 Eric Gunnerson
using System;
using System.Text;
struct RomanNumeral
{
    public RomanNumeral(short value) {
        if (value > 5000)
        throw(new ArgumentOutOfRangeException());
        
        this.value = value;
    }
    public static explicit operator RomanNumeral(short value) 
    {
        RomanNumeral    retval;
        retval = new RomanNumeral(value);
        return(retval);
    }
    
    public static implicit operator short(RomanNumeral roman)
    {
        return(roman.value);
    }
    
    static string NumberString(ref int value, int magnitude, char letter)
    {
        StringBuilder    numberString = new StringBuilder();
        
        while (value >= magnitude)
        {
            value -= magnitude;
            numberString.Append(letter);
        }
        return(numberString.ToString());
    }
    
    public static implicit operator string(
    RomanNumeral roman)
    {
        int        temp = roman.value;
        
        StringBuilder retval = new StringBuilder();
        
        retval.Append(RomanNumeral.NumberString(ref temp, 1000, "M"));
        retval.Append(RomanNumeral.NumberString(ref temp, 500, "D"));
        retval.Append(RomanNumeral.NumberString(ref temp, 100, "C"));
        retval.Append(RomanNumeral.NumberString(ref temp, 50, "L"));
        retval.Append(RomanNumeral.NumberString(ref temp, 10, "X"));
        retval.Append(RomanNumeral.NumberString(ref temp, 5, "V"));
        retval.Append(RomanNumeral.NumberString(ref temp, 1, "I"));
        
        return(retval.ToString());
    }
    
    private short value;
}
public class UserDefinedConversionsASimpleExample
{
    public static void Main()
    {
        short s = 12;
        RomanNumeral numeral = new RomanNumeral(s);
        
        s = 165;
        numeral = (RomanNumeral) s;
        
        Console.WriteLine("Roman as int: {0}", (int)numeral);
        Console.WriteLine("Roman as string: {0}", (string)numeral);
        
        short s2 = numeral;
    }
}


User-Defined Conversions: How It Works: Conversion Lookup

// This demo has compiling error
class S
{
}
class TBase
{
}
class T: TBase
{
    public static implicit operator T(S s) 
    {
        return(new T());
    }
}
public class ConversionLookup1
{
    public static void Main()
    {
        S myS = new S();
        TBase tb = (TBase) myS;
    }
}