Summary of As and forced conversion in C #

Source: Internet
Author: User
ArticleDirectory
    • 1.1.1 Summary
    • 1.1.2 text
    • 1.1.3 Summary
1.1.1 Summary

C # is a strongly typed language. In general, we 'd better avoid forcibly converting a type to another type, but sometimes type conversion is inevitable.

First, consider which operations can perform type conversion (skip the parse provided by. Net). Generally, we have the following options:

    • Convert using the as operator,
    • Use traditional C-style forced Transformation
    • Use is for a conversion test, and then use the as operator or force conversion

 

1.1.2 text

The correct choice should be to use the as operator as much as possible, because it is safer than forced transformation, it is also efficient at the runtime level (note that the AS and is operators do not execute any user-defined conversions, only when the runtime type matches the target conversion type, ).

Now we use a simple example to illustrate the difference between AS and forced conversion. First we define a factory to get different types of objects, and then we convert the unknown type to the custom type.

 

  Object  O  =  Factory. GetObject ();
Mytype t = O As Mytype;
If (T = Null )
{
// Conversion successful
}
Else
{
// Conversion Loss Rate
}


Object O = Factory. GetObject ();
Try
{
Mytype t = ( Mytype)O;
If (T ! = Null )
{
/// /Conversion successful
}
Else
{
/// /Conversion loss rate
}

}
Catch
{
/// /Exception Handling
}

 

Through the aboveCodeWe found that the as type conversion failure value is null and no exception is thrown, but if the conversion fails to be forced, an exception is thrown, so we need to add Exception Processing.

Now we have a preliminary understanding of As and forced conversion. Suppose we now define an abstract class Foo, and then foo1 inherits from it, and then define a base class logger, the implicit conversion between foo1 and logger types is as follows:

 Foo1 myfoo;  ///  /Inherits abstract class.  
Logger myfoo; /// /Base class.

Public Class Foo1: foo
{
Private Logger _ value;

/// <Summary>
/// Implicit custom type conversion.
/// </Summary>
/// <Param name = "foo1"> </param>
/// <Returns> </returns>
Public Static Implicit Operator Logger (foo1 foo1)
{
Return Foo1. _ value;
}
}

Now let's guess whether the following type conversion is successful (Note: From the Perspective of compiling and running type conversion ).

   Object  Myfoo  =  Container. Resolve  <  Foo  > ();  //  Retrieve type not foo1  

Try
{
Logger myfoo1 = (Logger) myfoo;
If (Myfoo1 ! = Null )
{
Console. writeline ( " Covert successful. " );
}
}
Catch
{
Console. writeline ( " Covert failed. " );
}

I believe that everyone who is smart has come up with the answer. The exciting moment is now, let's announce the answer: conversion failure throws an exception.

Figure 1 conversion failure result

 

First, we needCompile and runFrom the perspective of analysis, the myfoo type is system. object during compilation, then the compiler checks whether there is a type conversion from the object to the logger. If no proper conversion is found, the compiler will generate code to check the runtime type of myfoo compared with that of logger. Because the runtime type of myfoo is foo1, in addition, we have customized the type conversion from foo1 to logger. It is estimated that the conversion is successful! However, the conversion was not successful. Why? Let's take a look at the compiler's principle of implicit type conversion.

Figure 2 custom type conversion during compilation and Runtime

 

We found that the user-defined conversion operator only applies to the object's compile-time type, rather than the runtime type. OK now let's modify the code to let the compiler know the custom type.

 Using  (Iunitycontainer container  =     New  Unitycontainer ())
{
Unityconfigurationsection Section = (Unityconfigurationsection) Configurationmanager. getsection ( " Unity " ); // Obtain the configuration under the cfginer name "Custom class ".
Section. containers [ " Keep class " ]. Configure (container );
Object Tempfoo = Container. Resolve < Foo > (); // Retrieve type not foo1
Foo1 myfoo = Tempfoo As Foo1; // Use as to first convert an object to foo1
Try
{
Logger myfoo1 = (Logger) myfoo;
If (Myfoo1 ! = Null )
{
Console. writeline ( " Covert successful. " );
}
}
Catch
{
Console. writeline ( " Covert failed. " );
}

Console. readkey ();
}

Figure 3 successful Conversion Result

 

Now the type can be converted successfully. This is because the compiler uses our custom implicit conversion. Because the compilation type of myfoo is foo1, the compiler first checks whether foo1 and logger custom conversion types exist, since we have defined an implicit type conversion from foo1 to logger, the conversion is successful.

Through the above, we found the benefits of As, but one thing we should note is thatAs can only be used for reference type, not for Value Type. Then I have a problem. If we don't know whether to convert the value type or the reference type before the type conversion, what should we do? Now is the time to make the debut.

    bject   tempfoo  =  container. resolve     Foo  >  ();   //   obtain the type not foo1   
int Myint = tempfoo as int ; // compile error

As cannot be used for value type, because the value type cannot be null (note: in C #2.0, Microsoft provides the nullable type, which allows defining null values, that is, the Data Type of the null value. In this case, we should use forced type conversion.

 Object  Tempfoo  =  Container. Resolve  <  Foo  >  ();  //  Retrieve type not foo1  
Try
{
Int Myint = ( Int ) Tempfoo; // Conversion successful
If (Myfoo1 ! = Null )
{
Console. writeline ( " Covert successful. " );
}
}
Catch
{
Console. writeline ( " Covert failed. " );
}

We can find that it is similar to the forced conversion we used previously, and there are handling exceptions. Now let's modify our code to make it more concise and implement as follows:

 Object  Tempfoo  =  Container. Resolve  < Foo  >  ();  //  Retrieve type not foo1  
Int I = 0 ; // Value Type Conversion
If (Tempfoo Is Int )
{
I = ( Int ) Tempfoo;
}

Object Tempfoo = Container. Resolve < Foo > (); // Retrieve type not foo1
Logger myfoo1 = Null ; // Conversion of reference types
If (Tempfoo Is Logger)
{
Myfoo1 = Tempfoo As Logger;
}
1.1.3 Summary

The biggest difference between AS and forced conversion is how to handle custom conversions. The AS and is operators only check the runtime type of the converted object and do not perform other operations. If the runtime type of the converted object is neither the target type nor its derived type, the transformation will fail. However, forced transformation uses the conversion operator to perform the transformation operation, which includes any built-in Numerical Conversion (for example, long to int ).

In general, we should first consider using as for type conversion, then consider using is, and finally consider using forced conversion.

as

forced conversion

whether to throw an exception if the conversion fails

NO

Yes

supports conversion of value type and reference type

only reference types are supported

Yes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.