C # is an object-oriented language. In the object-oriented thinking, only objects can be described in classes. For example, Int, bool, Char, String, double, long and so on are all classes. For example, 30, 2.5, and "test" are all objects of the corresponding class.
static void Main(string[] args) { string istring = 30.ToString(); string dstring = 2.5.ToString(); string sstring = "test".ToString(); Console.WriteLine(string.Format("{0},{1},{2}", istring, dstring, sstring)); Console.ReadLine(); }
Output:
We can see that they have the tostring () method, so they are objects.
When writing code at ordinary times, defining data types must be used in addition to the above:
static void Main(string[] args) { Int32 i = 0; UInt32 j = 0; String str = "test"; Console.ReadLine(); }
This is actually a mechanism of. net, and. Net is a platform with C # and VB languages. Therefore,. Net defines a series of types that are mapped to different languages. int32 is int in C. Such a data type is called a primitive type. The Class Object in C # Must be generated using new. These classes can be expressed directly by constants. The primitive type is defined in. NET Framework and under the system namespace. Let's take a look at the type ing of primitive types in C.
| .Net Framework primitive type |
C # type |
Value Range |
Remarks |
|
System. Boolean |
Bool |
True/false |
/ |
| System. byte |
Byte |
0 ~ 255 |
Unsigned 8-digit integer |
| System. sbyte |
Sbyte |
-128 ~ 127 |
Signed 8-digit integer |
| System. Char |
Char |
0 ~ 65,535 |
Unsigned 16-digit integer |
| System. int16 |
Short |
-32,768 ~ 32,767 |
Signed 16-digit integer |
| System. uint16 |
Ushort |
0 ~ 65,535 |
Unsigned 16-digit integer |
| System. int32 |
Int |
-2,147,483,648 ~ 2,147,483,647 |
Signed 32-bit integer |
| System. int64 |
Long |
-9,223,372,036,854,775,808 ~
9,223,372,036,854,775,807 |
Signed 64-bit integer |
| System. uint64 |
Ulong |
0 ~ 18,446,744,073,709,551,615 |
Unsigned 64-bit integer |
| System. Single |
Float |
± 1. 5 × 10-45 ~ ± 3. 4 × 1038
(7-digit valid number) |
32-Bit Single-precision floating point number |
| System. Double |
Double |
± 5. 0 × 10-324 to ± 1. 7 × 10308
(15 to 16 valid digits) |
64-bit Double Precision Floating Point |
| System. Decimal |
Decimal |
± 1. 0 × 10-28 to ± 7. 9 × 1028
(27 to 28 valid digits) |
128-bit floating point number |
| System. String |
String |
Any string |
/ |
| System. uint32 |
Uint |
0 ~ 4,294,967,295 |
Unsigned 32-bit integer |
Except that the string type is the reference type (explained separately later), the other values are the value type.
The following describes the reference type and value type.
When learning C language, there is a concept of heap and stack.
Heap zone-the programmer allocates and releases, or the program ends with OS recycling. The allocation method is similar to a linked list.
Stack zone-the compiler automatically allocates and releases the stack and stores function parameter values and variable values.
The stack memory structure can quickly allocate and recycle memory, but the stack space is limited and excessive use will "overflow". Therefore, the stack is only allocated to commonly used data types that occupy a small amount of space; the heap memory structure is slow to allocate memory, but large space can be used to store large data volumes.
In C #, basically all data is stored in the "Heap" structure, which is called "managed heap" and monitored by. Net garbage collection. However, compared with the stack Heap Structure, the memory allocation efficiency is relatively low. In order to properly recycle garbage, the heap space allocated each time is slightly larger than the actual space required. It is not suitable for small data to use the heap space.
Let's take a look at the value type and reference type:
In C #, struct defines the value type and allocates memory directly on the stack.
/// <Summary> /// you can use struct to define a value type. // you can only implement interfaces for value types, but cannot inherit classes /// </Summary> public struct posipositivenumber: icloneable {// <summary> // Value Type field /// </Summary> private int number; // <summary> // static read-only field, as the initial value of the class // </Summary> Public readonly static structpositivenumber initialvalue = new structpositivenumber (); /// <summary> /// attribute /// </Summary> Public int number {get {return number;} set {If (value <= 0) {Throw new exception ();} This. number = value ;}/// <summary> // you can define the constructor, but it is different from the class, the default constructor still exists // </Summary> Public structpositivenumber (INT value) {If (value <= 0) {Throw new exception ();} This. number = value ;}/// <summary> // implement the clone method, returns the current object /// </Summary> /// <returns> </returns> Public object clone () {return New structpositivenumber (this. number );}}
Call
Static void main (string [] ARGs) {// declare the variable, assign structpositivenumber pnumber1 = structpositivenumber. initialvalue; increment = 1; // assign pnumber1 to pnumber2 structpositivenumber pnumber2 = pnumber1; // change pnumber2 value to pnumber2.number = 2; // view the printed result and change the pnumber2 value, however, pnumber1 console is not affected. writeline (pnumber1.number); // 1 Console. writeline (pnumber2.number); // 2 // reinitialize pnumber2 and change the initial value by generating the constructor. Pnumber2 = new structpositivenumber (3); console. writeline (pnumber2.number); // 3 // call clone to copy pnumber2 to pnumber1 pnumber1 = (structpositivenumber) pnumber2.clone (); console. writeline (pnumber1.number); // 3 // change the value of pnumber1, but the value of pnumber2 does not change pnumber1.number = 4; console. writeline (pnumber1.number); // 4 console. writeline (pnumber2.number); // 3 console. readline ();}
Result
Let's look at the definition of the reference type:
Public class classpositivenumber: icloneable {private int number; Public int number {get {return this. number;} set {If (value <= 0) {Throw new exception ();} This. number = value ;}// the reference type can be initialized to null by itself, without defining the initial value // public readonly static classpositivenumber initialvalue = new classpositivenumber (); Public classpositivenumber (INT value) {If (value <= 0) {Throw new exception ();} This. number = value;} public object clone () {return New classpositivenumber (this. number );}}
Call
Static void main (string [] ARGs) {classpositivenumber cnumber1; // The default value is null cnumber1 = New Numeric (1); classpositivenumber cnumber2 = cnumber1; cnumber2.number = 2; // you can see, the two references reference the same object console. writeline (cnumber1.number); // 2 console. writeline (cnumber2.number); // 2 // reinitialize cnumber2. The previous object has been discarded. cnumber2 = new classpositivenumber (3); console. writeline (cnumber2.number); // 3 // copy is a copy of an object, so it is two different objects cnumber1 = (classpositivenumber) cnumber2.clone (); console. writeline (cnumber1.number); // 3 cnumber1.number = 4; console. writeline (cnumber1.number); // 4 console. writeline (cnumber2.number); // 3 console. readline ();}
Result
Through the example, we can see that the value type has the following features:
A. use struct statement;
B. The class cannot be inherited, but the interface can be implemented (except the object class of course );
C. The value type uses the value type as the field, but the field cannot have the default value;
C. The default constructor must exist in the value type. After you define the constructor, the default non-parameter constructor still exists. In addition, only fields in the category class can be constructed, but attributes cannot be accessed. Symbol = is a value type, so a value type variable cannot be empty. Because the value type does not have a reference concept, there must be a value.
Code download: http://download.csdn.net/detail/yysyangyangyangshan/4452051