. Net (C #): more thorough understanding of out parameters from Il and Reflection emit

Source: Internet
Author: User

There are many articles on ref and out in C #. This article mainly analyzes the nature of out parameters from Il.

 

Directory

  • Out = ref + parameterattributes. Out
  • Call the ref and out methods through reflection
  • Emit build out or ref Parameters

 

 

Returned directory

Out = ref + parameterattributes. Out

Let's look at two out and ref methods.

Static void test_ref (ref int I)

{}

 

Static void test_out (Out int I)

{I = default (INT );}

 

Il:

. Method private hidebysig static void test_ref (int32 & I) cel managed

 

. Method private hidebysig static void test_out ([out] int32 & I) cel managed

 

As you can see, the out parameter is a ref parameter (the address of all the passed parameters can be understood as a pointer in C/C ++), but a [out] is added.

This can also be verified from the attributes attribute of the parameterinfo class in reflection.

Public class Program

{

Static void main (string [] ARGs)

{

VaR reffunc = typeof (Program). getmethod ("test_ref ");

VaR outfunc = typeof (Program). getmethod ("test_out ");

 

Foreach (VAR Pa in reffunc. getparameters ())

Console. writeline (Pa. attributes );

 

Foreach (VAR Pa in outfunc. getparameters ())

Console. writeline (Pa. attributes );

}

 

Public static void test_ref (ref int I)

{}

 

Public static void test_out (Out int I)

{I = default (INT );}

 

}

 

Output:

None

Out

 

The parameterinfo attribute of the ref parameter is none, the value is equal to 0, and the out parameter is the out enumerated value.

 

Returned directory

Call the ref and out methods through reflection

Since out is a ref, there is no difference in reflection calls. Reflection calls require an object array as a parameter. The Compiler certainly does not allow you to put an uninitialized variable in an array, even if it is used as an out parameter. At the same time, as long as the array is created, the elements in it are null by default. No matter whether you want to replace null with other values, the final ref or out parameters will change the corresponding values.

Static void main (string [] ARGs)

{

VaR M = typeof (Program). getmethod ("Doo ");

VaR Arg = new object [] {null, null };

M. Invoke (null, ARG );

Console. writeline ("{0} {1}", Arg [0], Arg [1]);

}

Public static void doo (ref int A, out int B)

{

A = B = 1;

}

 

Output two 1 s. The values are modified correctly.

 

 

Returned directory

Emit build out or ref Parameters

First, create a dynamic method that is the same as the previous doo method using the typebuilder that reflects emit!

 

Based on the knowledge above, in the definemethod method of typebuilder, both parameters are reference parameters of INT (typeof (INT ). makebyreftype (). To set the second parameter to out, you must call methodbuilder. defineparameter method, set parameterattributes. out can be performed on the specified parameter!

 

Code:

Static void createmethod (typebuilder TB)

{

VaR mbuilder = Tb. definemethod ("Doo ",

Methodattributes. Public | methodattributes. hidebysig | methodattributes. Static,

Callingconventions. Standard,

Null,

New Type [] {typeof (INT). makebyreftype (), typeof (INT). makebyreftype ()});

// Both ref and out are typeof (INT). makebyreftype ()

 

// Set the ref parameter name to

Mbuilder. defineparameter (1, parameterattributes. None, "");

// Set the out parameter to B.

// Set parameterattributes. Out for parameter B (otherwise it is the same as the ref parameter)

Mbuilder. defineparameter (2, parameterattributes. Out, "B ");

 

VaR ilgen = mbuilder. getilgenerator ();

// A = B = 1

Ilgen. emit (Opcodes. ldarg_0 );

Ilgen. emit (Opcodes. ldc_i4_1 );

Ilgen. emit (Opcodes. stind_i4 );

Ilgen. emit (Opcodes. ldarg_1 );

Ilgen. emit (Opcodes. ldc_i4_1 );

Ilgen. emit (Opcodes. stind_i4 );

 

Ilgen. emit (Opcodes. Ret );

}

 

OK, use reflector to open the doo method of the assembly we generated using emit. You will see:

 

 

Everything is correct!

Related Article

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.