Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   Conversion Operator Methods

Occasionally, you need to convert an object from one type to an object of a different type. For ex- ample, I’m sure you’ve had to convert a Byte to an Int32 at some point in your life. When the source type and the target type are a compiler’s primitive types, the compiler knows how to emit the neces- sary code to convert the object.

If the source type or target type is not a primitive, the compiler emits code that has the CLR per- form the conversion (cast). In this case, the CLR just checks if the source object’s type is the same type as the target type (or derived from the target type). However, it is sometimes natural to want to

convert an object of one type to a completely different type. For example, the System.Xml.Linq.X­ Element class allows you to convert an Extensible Markup Language (XML) element to a Boolean, (U)Int32, (U)Int64, Single, Double, Decimal, String, DateTime, DateTimeOffset, TimeSpan, Guid, or the nullable equivalent of any of these types (except String). You could also imagine that the FCL included a Rational data type and that it might be convenient to convert an Int32 object or a Single object to a Rational object. Moreover, it also might be nice to convert a Rational object to an Int32 or a Single object.

To make these conversions, the Rational type should define public constructors that take a single parameter: an instance of the type that you’re converting from. You should also define public instance ToXxx methods that take no parameters ( just like the very popular ToString method). Each method will convert an instance of the defining type to the Xxx type. Here’s how to correctly define conver- sion constructors and methods for a Rational type.

 

public sealed class Rational {

// Constructs a Rational from an Int32 public Rational(Int32 num) { ... }

 

// Constructs a Rational from a Single public Rational(Single num) { ... }

 

// Converts a Rational to an Int32 public Int32 ToInt32() { ... }

 

// Converts a Rational to a Single public Single ToSingle() { ... }

}

 

By invoking these constructors and methods, a developer using any programming language can convert an Int32 or a Single object to a Rational object and convert a Rational object to an Int32 or a Single object. The ability to do these conversions can be quite handy, and when design- ing a type, you should seriously consider what conversion constructors and methods make sense for your type.

In the previous section, I discussed how some programming languages offer operator overload- ing. Well, some programming languages (such as C#) also offer conversion operator overloading. Conversion operators are methods that convert an object from one type to another type. You define a conversion operator method by using special syntax. The CLR specification mandates that conversion


overload methods be public and static methods. In addition, C# (and many other languages) re- quires that either the parameter or the return type must be the same as the type that the conversion method is defined within. The reason for this restriction is that it enables the C# compiler to search for a possible operator method to bind to in a reasonable amount of time. The following code adds four conversion operator methods to the Rational type.



 

public sealed class Rational {

// Constructs a Rational from an Int32 public Rational(Int32 num) { ... }

 

// Constructs a Rational from a Single public Rational(Single num) { ... }

 

// Converts a Rational to an Int32 public Int32 ToInt32() { ... }

 

// Converts a Rational to a Single public Single ToSingle() { ... }

 

// Implicitly constructs and returns a Rational from an Int32 public static implicit operator Rational(Int32 num) {

return new Rational(num);

}

 

// Implicitly constructs and returns a Rational from a Single public static implicit operator Rational(Single num) {

return new Rational(num);

}

 

// Explicitly returns an Int32 from a Rational public static explicit operator Int32(Rational r) {

return r.ToInt32();

}

 

// Explicitly returns a Single from a Rational public static explicit operator Single(Rational r) {

return r.ToSingle();

}

}

 

For conversion operator methods, you must indicate whether a compiler can emit code to call a conversion operator method implicitly or whether the source code must explicitly indicate when the compiler is to emit code to call a conversion operator method. In C#, you use the implicit keyword to indicate to the compiler that an explicit cast doesn’t have to appear in the source code in order to emit code that calls the method. The explicit keyword allows the compiler to call the method only when an explicit cast exists in the source code.

After the implicit or explicit keyword, you tell the compiler that the method is a conversion operator by specifying the operator keyword. After the operator keyword, you specify the type that an object is being cast to; in the parentheses, you specify the type that an object is being cast from.


Defining the conversion operators in the preceding Rational type allows you to write code like this (in C#).

 

public sealed class Program { public static void Main() {

Rational r1 = 5; // Implicit cast from Int32 to Rational Rational r2 = 2.5F; // Implicit cast from Single to Rational

 

Int32 x = (Int32) r1; // Explicit cast from Rational to Int32 Single s = (Single) r2; // Explicit cast from Rational to Single

}

}

 

Under the covers, the C# compiler detects the casts (type conversions) in the code and internally generates IL code that calls the conversion operator methods defined by the Rational type. But what are the names of these methods? Well, compiling the Rational type and examining its meta- data shows that the compiler produces one method for each conversion operator defined. For the Rational type, the metadata for the four conversion operator methods looks like this.

 

public static Rational op_Implicit(Int32 num) public static Rational op_Implicit(Single num) public static Int32 op_Explicit(Rational r) public static Single op_Explicit(Rational r)

 

As you can see, methods that convert an object from one type to another are always named op_ Implicit or op_Explicit. You should define an implicit conversion operator only when precision or magnitude isn’t lost during a conversion, such as when converting an Int32 to a Rational. However, you should define an explicit conversion operator if precision or magnitude is lost during the conver- sion, as when converting a Rational object to an Int32. If an explicit conversion fails, you should indicate this by having your explicit conversion operator method throw an OverflowException or an InvalidOperationException.

       
   
 
 


C# has full support for conversion operators. When it detects code where you’re using an object of one type and an object of a different type is expected, the compiler searches for an implicit conver- sion operator method capable of performing the conversion and generates code to call that method. If an implicit conversion operator method exists, the compiler emits a call to it in the resulting IL code. If the compiler sees source code that is explicitly casting an object from one type to another type, the compiler searches for an implicit or explicit conversion operator method. If one exists, the compiler emits the call to the method. If the compiler can’t find an appropriate conversion operator method, it issues an error and doesn’t compile the code.

       
   
 
 

 

To really understand operator overload methods and conversion operator methods, I strongly encourage you to examine the System.Decimal type as a role model. Decimal defines several constructors that allow you to convert objects from various types to a Decimal. It also offers several ToXxx methods that let you convert a Decimal object to another type. Finally, the type defines sev- eral conversion operators and operator overload methods as well.

 

 


Date: 2016-03-03; view: 810


<== previous page | next page ==>
Nbsp;   Operator Overload Methods | Nbsp;   Extension Methods
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.009 sec.)