C # methods Study Notes

Source: Internet
Author: User

Constructor

If you do not define a constructor for a class, it will automatically generate

Public class sometype {
}
Public class sometype {
Public sometype (): base (){}
}

The compilation results of the two sections of code are the same.

If the parent class is an abstract class, the access permission to the parent class constructor is protected.

Otherwise, it is public. If the parent class does not provide a non-argument constructor, The subclass must display the constructor that calls the parent class; otherwise, an error is returned. If the parent class is static or abstract class, the compiler will not generate the default constructor.

A class can define multiple constructors, but must have different signatures.

A lei constructor must implement the base class constructor. Otherwise, the base class field will

Inaccessible (because fields are often initialized in constructors ). So if you do not display

Call. The c # compiler will call one for Automatic Generation. To the end

In system. object, nothing is done because it has no field. Direct return

Sometimes the creation of a class does not require constructors.

For example, use object's memberwiseclone.

For example, deserializing an object (json/xml ).

Note: you do not need to call the virtual method in the constructor.

Fields that have not been initialized in the virtual method will generate unpredictable behavior.

Let's look at the following example.

Internal sealed class sometype {
Private int32 m_x = 5;
}

. Method public hidebysig specialname rtspecialname
Instance void. ctor () cel managed
{
// Code size 14 (0xe)
. Maxstack 8
Il_0000: ldarg.0
Il_0001: ldc. i4.5
Il_0002: st1_int32 sometype: m_x
Il_0007: ldarg.0
Il_0008: call instance void [mscorlib] system. object:. ctor ()
Il_000d: ret
}

From il, we know that the sometype constructor contains

The code that assigns m_x value 5 also contains the method for calling the parent class object constructor.

This shows that the c # compiler allows you to initialize the instance fields in inline mode and put them into the constructor.

Internal sealed class sometype {
Private int32 m_x = 5;

Public sometype (){

M_x = 1;

}
}

The above code is nonstandard and insecure, and a better way of writing is:

Internal sealed class sometype {
Private int32 m_x;

Public sometype (){

M_x = 5;

}
}


Function of the Value Type instance

The value type is not added by default without constructors, but you can define a constructor with parameters for it.

After the struct is used, the variable is initialized to 0/null. The value type can be directly assigned, or

Assign values using constructor, but its constructor cannot be a non-argument constructor. Otherwise, an error is reported.

"Error cs0568: structs cannot contain explicit parameterless
Constructors ."

C # The Compiler does this to make the developer less confused about calling the constructor.

Because the value type does not have a constructor without parameters, the following code cannot be executed (I.

Internal struct somevaltype {
// You cannot do inline instance field initialization in a value type
Private int32 m_x = 5;
}

 
Type constructor
Clr not only supports instance constructor, but also supports Type constructor (static constructor. Class and body constructor), or even interface Constructor (not supported by c ).

Constructor of reference type

Internal sealed class somereftype {
Static somereftype (){
// This executes the first time a somereftype is accessed.
// Execute when you enter this type for the first time
}
}
Constructor of Value Type
Internal struct somevaltype {
// C # does allow value types to define parameterless type constructors.
Static somevaltype (){
// This executes the first time a somevaltype is accessed.
}
}
The Value Type constructor is not executed
Internal sealed class somereftype {
Static somereftype (){
Console. writeline ("constructor of reference type executed ");
}
}
Internal struct somevaltype {
Public static int _ testint;
Static somevaltype (){
Console. writeline ("Value Type constructor executed ");
}
}
Class program {
Static void main (string [] args ){
Somereftype s = new somereftype ();
Somevaltype [] svt = new somevaltype [1];
Console. read ();
}
}

Test shows that the Type constructor In the struct is executed only when the instance constructor is used.

Another test code:

Internal sealed class somereftype {
Public static int _ testint;
Static somereftype (){
_ Testint = 1;
Console. writeline ("Type constructor of the reference type is executed ");
}
Public somereftype (){
Console. writeline ("the constructor of the reference type is executed ");
}
}
Internal struct somevaltype {
Public static int testint;
Static somevaltype (){
Console. writeline ("Value Type constructor executed ");
}
Private string test;
Public somevaltype (string value ){
Console. writeline ("constructor of value Type instance executed" + value );
Test = value;
}
}
 
 
Class program {
Static void main (string [] args ){
Display (0 );
Somereftype s = new somereftype ();
Display (1 );
Somereftype s2 = new somereftype ();
Display (2 );
Somevaltype [] svt = new somevaltype [1];
Display (3 );
Svt [0] = new somevaltype ("test ");
Display (4 );
Console. read ();
}
Static void display (object ob ){
Console. writeline (datetime. now. tostring () + "" + ob. tostring ());
}
}

And their execution sequence

In addition, the Type constructor is executed only once in the program. So we can use it for Singleton mode.

Clr does not know that operator overloading occurs, because during compilation

Various operators are produced with corresponding code. For example, + is produced as an addition function.

Public sealed class complex {
Public static complex operator + (complex c1, complex c2 ){
// To do
}
}

Manually reload an operator for Class

Public class classa {
Public static int operator + (classa c1, int c2 ){
Return ++ c2;
// To do
}
}

Static void main (string [] args ){
Int a = 0;
Int B = 0;
Int c = 0;
C = a + B;
Classa ca = new classa ();
Console. writeline (ca + 1 );
Console. read ();
}

The operators that can be reloaded are very limited, except for the common +-operators.

For more reloads in clr, see

He actually called

Op_addition method,

But neither recycltor nor il dasm can see that method...

View results

Private static void main (string [] args)
{
Int;
Int B;
Int c;
A = 0;
B = 0;
C = 0;
C = a + B;
Return;
}

. Method private hidebysig static void main (string [] args) cel managed
{
. Entrypoint
// Code size 12 (0xc)
. Maxstack 2
. Locals init ([0] int32,
[1] int32 B,
[2] int32 c)
Il_0000: nop
Il_0001: ldc. i4.0
Il_0002: stloc.0
Il_0003: ldc. i4.0
Il_0004: stloc.1
Il_0005: ldc. i4.0
Il_0006: stloc.2
Il_0007: ldloc.0
Il_0008: ldloc.1
Il_0009: add
Il_000a: stloc.2
Il_000b: ret
} // End of method program: main

My personal opinion:

Operator Overloading usually leads to ambiguity and is not promoted unless used for special performance purposes. For example, in some basic data types, you need to rewrite the comparison = and! =.
1 c # Extension Method

Starting with a simple example

Namespace system {
Public static class class4 {
Public static string with (this string content, params string [] strs ){
Return string. format (content, strs );
}
}
}
.................. Main program ..............
Using system;
Namespace clrlearn {
Class program {
Static void main (string [] args ){
Display ("hi {0} and {1 }! ". With (" ladys "," gentleman! "));
Console. read ();
}
Static void display (object ob ){
Console. writeline (datetime. now. tostring () + "" + ob. tostring ());
}
}
}

 

It is worth noting that the namespace of the extension method is not referenced in the program. cs file,

Because his namespace is system... it is both good and bad. For many people, it is reasonable to say that the namespace should not take the default

Notes:

1 c # Only extension methods are supported. Extension properties and events are not supported... And so on

2. There is no limit to the method name. The first parameter must contain this

2. Perform expansion for the set

Public static void showitems <t> (this ienumerable <t> collection ){
Foreach (var item in collection)
Console. writeline (item );
}
Static void main (string [] args ){
String statment = "hi {0} and {1}". with ("ladys", "gentleman ");
Display (statment );
Statment. showitems <char> ();
Console. read ();
}

3. More details
After you use this parameter to extend the method, the program assembly will add the following content on the corresponding static class during compilation. This makes it easy to find a call.

[Attributeusage (attributetargets. method | attributetargets. class | attributetargets.
Assembly)]
Public sealed class extensionattribute: attribute {
}

In fact, system. core. dll must be referenced during runtime.

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.