Summary of the C method

  • 2020-05-12 03:02:56
  • OfStack

C # method
1: instance constructors and classes
2: instance constructors and structures
3: type constructor
4: operator overload method
5: transform operator methods
6: extend the method
7: partial method
1: instance constructors and classes
A constructor is a special method that allows you to initialize an instance of a type to a good state. When you create an instance of a reference type, you allocate memory for the data fields of the instance, then initialize additional fields of the object (type object Pointers and synchronized indexes), and finally call the constructor to set the initial state of the object. Constructors cannot be inherited, so they cannot be modified by virtual, new, override, sealed, and abstract. If no constructors are defined, the compiler will define an public constructor without arguments, but if an abstract class is defined, the compiler will define a constructor of protected without arguments
Creating an instance of a class does not necessarily mean calling the constructor.
1: use the MemberwiseClone() method of Object. His job is to create a shallow copy of the current System.Object. The internal mechanism is to allocate memory, initialize additional fields of the object (type object Pointers and synchronized indexes), and then copy the byte data of the source object into the new object. As you can see from the code below, MemberwiseClone() implements object replication rather than simple object references.

class Program
    {
        public int X;
        static void Main(string[] args)
        {
            Program p = new Program();
            p.X = 1;
            Program q = (Program)p.MemberwiseClone();
            Program z = p;
            p.X = 2;
            Console.WriteLine("p.X=" + p.X);// Output: p.X=2
            Console.WriteLine("q.X=" + q.X);// Output: q.X=1
            Console.WriteLine("z.X=" + z.X);// Output: z.X=2
            Console.Read();
        }
    }

2: deserialization. In network programming, it is common to serialize an object into base 2, then transfer it out, and deserialize it back to the original object at the receiving end. Deserialization USES classes
Method of System. Runtime. Serialization. FormatterServices public static object GetUninitializedObject (Type type) or
public static object GetSafeUninitializedObject(Type type) allocates memory without calling the constructor of the object to be deserialized within either method.
Field initialization code will be the compiler automatically added to the corresponding constructor, non-static fields initialization code will be automatically added to the instance constructor, static fields of the initialization code is added to the static constructor, if you have multiple fields in the code is initialized, there are more than one constructor, the initialization code in each constructor will have one copy, it will allow you to generate files (such as DLL EXE file).
The code to prove this point is as follows:

public class SomeType
    {
        public  int x=1,y=2,z=3;
        public SomeType() { }
        public SomeType(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
        public SomeType(int x)
        {
            this.x = x;
        }
}
// after IL Decompile, method SomeType(int x, int y) The following code 
.method public hidebysig specialname rtspecialname 
        instance void  .ctor(int32 x,
                             int32 y) cil managed
{
  //  Code size        45 (0x2d)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  stfld      int32 MyTest.SomeType::x
  IL_0007:  ldarg.0
  IL_0008:  ldc.i4.2
  IL_0009:  stfld      int32 MyTest.SomeType::y
  IL_000e:  ldarg.0
  IL_000f:  ldc.i4.3
  IL_0010:  stfld      int32 MyTest.SomeType::z
  IL_0015:  ldarg.0
  IL_0016:  call       instance void [mscorlib]System.Object::.ctor()
  IL_001b:  nop
  IL_001c:  nop
  IL_001d:  ldarg.0
  IL_001e:  ldarg.1
  IL_001f:  stfld      int32 MyTest.SomeType::x
  IL_0024:  ldarg.0
  IL_0025:  ldarg.2
  IL_0026:  stfld      int32 MyTest.SomeType::y
  IL_002b:  nop
  IL_002c:  ret
} // end of method SomeType::.ctor

The initialization code is executed, the other constructors contain the initialization code, and then the assignment code in the constructor is executed. To solve this code bloat problem, it is very simple to write the initialization code in the no-argument constructor and let the other constructors call.
2: instance constructors and structures
The workings of a value type to a reference type, value types don't need to define a constructor, the earth would not stop the value type instantiation, the compiler will produce no by default, no arguments constructor if you display statement not constructor, compiled by no, error "structure cannot contain explicit no-arg constructor". Since the value type is stored in the stack, there is no need to reference the data in the heap, so we can assign the value directly at the time of definition, (int i=0; string s a = ""; Point p; p. X = 2) He doesn't need new at all, new is of course ok, the call constructor will initialize all the fields to the default value of the corresponding type, the example is as follows:

public struct Point
    {
        public int x, y;
        //public Point() { }// False: a structure cannot contain an explicit parameterless constructor 
        //public int z = 4;// Error: the structure cannot have an instance field initializer 
        //public Point(int x) // Before controlling the return caller, the field" Point.y "Must be fully assigned , To solve this problem, give it manually y add 1 Let's say it's a default, 
        // You can also add this=new Point(); Initializes the values of all fields to 0 or null
        //{
        //    this.x = x;
        //}
        public void Test()
        {
            Point p;
            p.x = 1;
            p.y = 2;
            Console.WriteLine(p.x+","+p.y);// The output 1,2
        }
    }

Structural features:
1: the definition of a no-argument constructor cannot be displayed
2: cannot be initialized while defining a field
3: when you declare the argument constructor, initialize all the fields
3: type constructor
The instance constructor is the static constructor, which sets the initialization state of the type. The static constructor can only have one, and it has no arguments, and it cannot be decorated with access modifiers. The default is private, which is called by the compiler. Examples are as follows:

public class SomeType
    {
        public static int x = 520;
        static SomeType()
        {
            x = 112;
        }
    }

    // with .NET reflector View the source code, as follows 
    public class SomeType
    {
        public static int x ;
        static SomeType()
        {
            x = 520;
            x = 0x70;
        }
        public SomeType() { }
    }

Definition in a static field and initialization, the compiler will automatically generate a type constructor (static constructor), and plug the initialization code of a static field in front of the type constructor, can be seen from the above code, initialization and in the type constructor defined initialization you just need to 1, and 112 x70 hexadecimal to 0, so in the code see hexadecimal also need not make a fuss, no performance issues involved, if defines a static field, but there was no one initialization, the compiler will not generate type constructor. But static fields are still initialized. In fact, both static and non-static fields are automatically initialized by the compiler. int type is initialized to 0. bool: False; string: null, that is why you are instantiated entity, some fields you don't have the initialization, but not an error, and you know the value of the string is not initialized null, meaning that the compiler will help you initialize your not initialize fields, however, in the method defined in a local variable is the need to initialize, if you don't initialize, will report an error "use no assignment of the local variable X".
4: operator overload method
To achieve operator overloading, you only need to make sure that there are two things, and everything else is just a cloud:
1: operator overload methods must be public and static methods
2: the operator overload method has at least one parameter of the same type as the method currently defined. This condition is required so that the compiler can find the action method to bind in a reasonable amount of time, as shown below

public class Complex
    {
        public int data;
        public Complex(int data)
        {
            this.data = data;
        }
        public static Complex operator +(Complex c1, Complex c2)
        {
            return new Complex(c1.data+c2.data);
        }
        public void Test()
        {
            Complex c1 = new Complex(1);
            Complex c2 = new Complex(2);
            Complex c3 = c1 + c2;
            Console.WriteLine(c3.data);// The output 3
        }
    }

5: transform operator methods
To implement the conversion operator method, the condition and the condition of the operator overload method are 1, as shown below:

public class Rational
    {
        public Rational(int data)
        {
            this.data = data;
        }
        public Rational(char data)
        {
            this.data = (int)data;
        }
        // Implicit type conversion :int->Rational
        public static implicit operator Rational(int data)
        {
            return new Rational(data);
        }
        // Implicit type conversion :char->Rational
        public static implicit operator Rational(char data)
        {
            return new Rational(data);
        }
        // Display type conversion  Rational->int
        public static explicit operator int(Rational val)
        {
            return val.data;
        }
        // Display type conversion  Rational->char
        public static explicit operator char(Rational val)
        {
            return Convert.ToChar(val.data);
        }
        public void Test()
        {
            Rational r1 = 1;// will int The type is implicitly converted to Rational
            Rational r2 = '2';// will char The type is implicitly converted to Rational
            int i = (int)r1;// will Rational Type display converted to int
            char c = (char)r2;// will Rational Type display converted to char
            Console.WriteLine("i=" + i);// Output: i=1
            Console.WriteLine("c=" + c);// Output: c=2
        }

        int data;
    }

In C++, you don't need to write any code for implicit and display type conversions at all. Just have the public constructor, public Rational(int data), Rational r=1. Compiler will do 1 cut trying to find ways to convert int type to Rational, when it is found that the constructor, he said all don't say to help you convert, because it's sometimes very pit dad, are you a int type they became Rational without reason, and you don't know what's going on, sometimes in order to solve this problem, also have to define a class (Uint) to encapsulate int, then the constructor to Rational (Uint data), C# doesn't have that problem, but if you want to do implicit type conversion, write your own code.
6: extend the method
Conditions for implementing the extended method:
1: the class that defines the extension method must be a non-generic static class
2: the class must have its own scope, that is, it cannot be an inner class
3: the methods must be public and static
4: the first parameter of the method must be decorated with this. The first parameter is the type you want to extend. The example is as follows:

public static class StringExtensions
    {
        public static int ToInt(this string s)
        {
            return Convert.ToInt32(s);
        }
        public void Test()
        {
            string s = "2";
            Console.WriteLine(s.ToInt());
        }
}

7: partial method
You know,

Related articles: