Csharp/C Sharp/Data Types/Casting Conversions
Версия от 15:31, 26 мая 2010; (обсуждение)
Содержание
- 1 An example that uses an implicit conversion operator
- 2 Casting int float and byte
- 3 Classes and Pre and Post Conversions
- 4 Conversion Lookup
- 5 Conversions: Numeric Types
- 6 Conversions:Numeric Types:Checked Conversions
- 7 Conversions:Numeric Types:Conversions and Member Lookup
- 8 Conversions:Numeric Types:Explicit Numeric Conversions
- 9 Conversions of Classes (Reference Types)\To an Interface the Object Might Implement
- 10 Conversions of Classes (Reference Types):To the Base Class of an Object
- 11 illustrates casting objects
- 12 InvalidCastException
- 13 Numeric Types: Checked Conversions
- 14 The use of the cast operator
- 15 Use an explicit conversion
- 16 User-Defined Conversions:A Simple Example
- 17 User-Defined Conversions: How It Works: Conversion Lookup
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;
}
}