C#学习笔记

本文详细介绍了C#中的数组,包括一维数组、多维数组和交错数组的声明与使用。接着讲解了数据类型,如值类型与引用类型、局部变量与成员变量、装箱与拆箱、枚举类型和字符串常量。此外,还涵盖了泛型集合,如List和Dictionary的使用方法。最后,探讨了类和对象的概念,包括常量、字段、方法、属性、构造函数以及静态和实例成员的差异。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、数组

数组一般用于存储同一种类型的数据,或者说,数组是相同类型的对象的集合。
数组是一种引用类型,而不是值类型。数组是按照数组名、数据元素的类型和维数来描述的。
数组分为一维数组和多维数组,多维数组。

数组声明

声明数组时,既可以一开始就指定数组元素的个数,也可以一开始不指定元素个数,而是在使用数组元素前动态地指定元素个数。但是不论采用哪种方式,一旦元素个数确定后,数组的长度就确定了。

以一维数组为例:
例如:
int[ ] a = new int[30]; //创建-一个包含30个int型元素的数组a,并在定义时指定元素个数为30一开始就指定数组元素个数

string[ ] b;
int number =int. Parse (Console . ReadLine( )); *//从键盘接收元素个数*
b = new String[number];*//指定数组b共有numer个元素*(**一开始不指定元素个数)**

也可以在声明语句中直接用简化形式为各元素赋初值,例如:

string[ ] mystring = {"first", "second" , "third"};

或者写为

string[ ] mystring = new string[ ] {"first", "second" , "third"};

在这里插入图片描述

多维数组

多维数组指维数大于1的数组,常用的是:二维数组和三维数组。从概念上来说,二维数组类似于网格(矩形网格和非矩形网格),三维数组则类似于立方体。
C#语言支持两种类型的二维数组,一种是二维矩形数组,另一种是二维交错数组。

在这里插入图片描述
在这里插入图片描述

交错数组

交错数组相当于一维数组的每一个元素又是一个数组,也可以把交错数组称为“数组的数组"。
如果按行列来排列数组的元素,可以将交错数组理解为每一行的列数可以相同,也可以不相同。
下面是交错数组的一种定义形式:

int[ ][ ] n1 = new int[2][ ]
{
new int[ ] {2,4,6},
new int[ ] {1,3,5,7,9}
};

在定义交错数组时,每个元素的new运算符不能省略。
注意
上面定义的数组也可以写为

int[ ][ ] n1 =new int[ ][ ] { new int[ ] {2,4,6}, new int[ ] {1,3,5,7,9} };

或者写为

int[ ][ ] n3 = { new int[ ] (2,4,6}, new int[ ] (1,3,5,7,9} };

还有一点要说明,交错数组的每一个元素既可以是一维数组,也可以是多维数组。例如,下
面的语句中每个元素又是一个二维数组:

int[ ][,] n4 = new int[3][,]
new int[,] { {1,3}{5,7} },
new int[,] { 0,2}{4,6}{8,10} },
new int[,] { {11,22}{99,88}{0,9} }

[例3-3]交错数组的用法。

using System;
namespace ArrayExample2
class Program
public static void Main( )
{
	string[ ][ ] b = new string[3][ ];
	b[0] = new string[2] { "b11", "b12” }
	b[1] = new string[3] { "b21", "b22""b23" };
	b[2] - new string[5] { "a", "e", "i", "o", "u" };
	for (int i = 0; i < b.Length; i++)
	{
		for (int j=0; j < b[i].Length; j++)
		{
			Console.Write("b[{0}][{1}1={2} ", i, j, b[i][j]);
		}
		Console.writeLine( );
	}
	Console. ReadLine( );
}
输出结果: 
b[0][0]=b11 b[0][1]=b12
b[1][0]=b21 b[11[1]=b22 b[1][2]=b23
b[2][0]=a b[2][1]-e b[2][2]=i b[2][3]=0 b[2][4]=u
}

参数数组

有时,当声明一个方法时,您不能确定要传递给函数作为参数的参数数目。C# 参数数组解决了这个问题,参数数组通常用于传递未知数量的参数给函数。
在使用数组作为形参时,C# 提供了 params 关键字,使调用数组为形参的方法时,既可以传递数组实参,也可以传递一组数组元素。
使用 params 关键字可以指定采用数目可变的参数的方法参数。 参数类型必须是一维数组。
在方法声明中的 params 关键字之后不允许有任何其他参数,并且在方法声明中只允许有一个 params 关键字。
如果 params 参数的声明类型不是一维数组,则会发生编译器错误 CS0225。
使用 params 参数调用方法时,可以传入:
1.数组元素类型的参数的逗号分隔列表。
2.指定类型的参数的数组。
3.无参数。
如果未发送任何参数,则 params 列表的长度为零。
params 的使用格式为:

public 返回类型 方法名称( params 类型名称[] 数组名称 )

下面的示例演示可向 params 形参发送实参的各种方法。


public class MyClass
{
    public static void UseParams(params int[] list)
    {
        for (int i = 0; i < list.Length; i++)
        {
            Console.Write(list[i] + " ");
        }
        Console.WriteLine();
    }

    public static void UseParams2(params object[] list)
    {
        for (int i = 0; i < list.Length; i++)
        {
            Console.Write(list[i] + " ");
        }
        Console.WriteLine();
    }

    static void Main()
    {
        // You can send a comma-separated list of arguments of the
        // specified type.
        UseParams(1, 2, 3, 4);
        UseParams2(1, 'a', "test");

        // A params parameter accepts zero or more arguments.
        // The following calling statement displays only a blank line.
        UseParams2();

        // An array argument can be passed, as long as the array
        // type matches the parameter type of the method being called.
        int[] myIntArray = { 5, 6, 7, 8, 9 };
        UseParams(myIntArray);

        object[] myObjArray = { 2, 'b', "test", "again" };
        UseParams2(myObjArray);

        // The following call causes a compiler error because the object
        // array cannot be converted into an integer array.
        //UseParams(myObjArray);

        // The following call does not cause an error, but the entire
        // integer array becomes the first element of the params array.
        UseParams2(myIntArray);
    }
}
/*
Output:
    1 2 3 4
    1 a test

    5 6 7 8 9
    2 b test again
    System.Int32[]
*/

实例:

using System;

namespace ArrayApplication
{
   class ParamArray
   {
      public int AddElements(params int[] arr)
      {
         int sum = 0;
         foreach (int i in arr)
         {
            sum += i;
         }
         return sum;
      }
   }
      
   class TestClass
   {
      static void Main(string[] args)
      {
         ParamArray app = new ParamArray();
         int sum = app.AddElements(512, 720, 250, 567, 889);
         Console.WriteLine("总和是: {0}", sum);
         Console.ReadKey();
      }
   }
}

二、数据类型

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

值类型与引用类型

值类型:直接存储数据
声明在栈中
数据存储在栈中。
引用类型:(存储数据的引用)
声明在栈中,数据存储在堆中,栈中存储该数据的引用。

局部变量,成员变量

局部变量(定义在方法内部的变量。)
特点
1–没有默认值必须自行设定初始值,否则不能使用。
2–方法被调用时,存在栈中,方法调用结束时从栈中清除。
成员变量(在类中定义的变量称为成员变量)
作用范围:在整个类中都有效

拆装箱

装箱

引用类型总是分配在托管堆上,而值类型总是分配在堆栈上。装箱是指将值类型隐式转换为引用类型。
对于值类型而言,装箱的具体过程为:首先分配一个对象实例,然后将值类型的值复制到该实例中。
装箱前后不是同一个实例。对于引用类型而言,装箱前后都共享同一个实例。


int i=10;
object o= i;//将 int型的变量i隐式转换为引用类型并将其赋给object类型的变量。

在C#类型系统中,存在最为常见的4种装箱,具体如下:
1.从任何值类型(包括枚举类型)到object类型。
2.从任何值类型(包括枚举类型)到System.ValueType类型。
3.从任何值类型到值类型实现的任何接口类型。
4.从任何枚举类型到System.Enum类型。
在这里插入图片描述

拆箱

拆箱是指将引用类型隐式转换为值类型。拆箱的具体操作包括以下两个步骤
(1)检查该对象实例是否为给定值类型的一个装了箱的值。
(2)将值从实例中复制出来。

int i=10;
object o = i;
int j = (int)o; //将引用类型o转换为int型的的值并赋给int型的变量j

在C#类型系统中,存在最为常见的4种拆箱,具体如下:
1.从object类型到任何值类型(包括枚举类型)。
2.从System.ValueType类型到任何值类型(包括枚举类型)。
3.从任何接口类型到实现了该接口类型的值类型。
4.从System.Enum类型到任何枚举类型。
在这里插入图片描述
拆装箱消耗性能
可以通过重载 泛型避免。

枚举类型

枚举类型是为一组在逻辑上密不可分的整数值提供便于记忆的符号。它是把一组相同类型、表达固定含义的数据作为一个集合放到一起,形成新的数据类型。
枚举类型也是一种值类型,它具有命名常量的独特的类型。每个枚举类型都有一个基础类型,该基础类型必须为byte、sbyte、short、 ushort、 int、 uint、 long 或ulong.其中,默认的基础类型为int。
枚举类型一般包含-一个或多 个枚举值,每一一个枚举值之间用逗号(,) 分隔。枚举值又称为枚举数,它的默认基础类型为int。默认情况下,第一个枚举数的值为0,后面的每一个枚举数的值依次增1。
在这里插入图片描述

字符串常量

string a="帅哥";
string b="帅哥";
string c="123";

在这里插入图片描述

字符串常量具备字符串池特性
字符串常量在创建前,首先在字符串池中查找是否存在相
同文本。如果存在,则直接返回该对象引用;如果不存在,则
开辟空间存储。
目的:提高内存利用率。
字符串具有不可变性
字符串常量旦进入内存 ,就不得再次改变。 因为如果在
原位置改变会使其他对象内存被破坏,导致内存泄漏。当遇到
字符串变量引用新值时,会在内存中新建一个字符串 ,将该字
符串地址交由该变量引用。

在这里插入图片描述
优点:避免产生垃圾
可以在原有空间修改字符串
适用性:频繁对字符串进行(增加 替换 移除)操作

常用方法
在这里插入图片描述

泛型集合

列表和排序列表List<数据类型>

用处:存东西但不知道具体存多少时

列表是指-系列元素的组合,列表中可以有重复的元素。
List泛型类表示可通过索引访问的强类型对象列表,该类提供了对列表进行搜索、排序和
操作的方法。
常用方法如下。
Add方法:将指定值的元素添加到列表中。
Insert方法:在列表的中间插人一 个新元素。
Contains方法:测试该列表中是否存在某个元素。

using System;
using System. Collections . Generic; 
namespace ListExample
{
	class Program
	{
		static void Main( ) 
		{
			List<string> list =new List<string>( );
			list .Add("张三");
			list .Add("李四");
			list. Insert(0"王五");
			if (list.Contains("赵六") == false)
			{
				list .Add ("赵六");
			}
			foreach (var item in list)
			{
				Console .WriteLine (item) ;
			}
			for (int i - 0; i < list.Count; i++)
			{
			Console. writeLine("list[{0}]={1}", i, list[i]);
			}
			list. Remove ("张三");
			list.Clear( );
			Console . ReadLine( ) ;
		}
	}
}

如果是数字列表,还可以对其进行求和、求平均值以及求最大数、最小数等。例如:

List<int> list = new List<int>( );
list .AddRange (new int[ ] { 12, 85, 20 });
Console. WriteLine (list.Sum( )) ;//结果为45
Console. WriteLine (list.Average( ));//结果为11.25
Console.WriteLine (list.Max( ));//结果为20
Console.WriteLine (list.Min( )) ;//结果为5

字典和排序字典

Dictionary<TKey, TValue>泛型类提供了从一组键 到一组值的映射。字典中的每个添加项都一个值及其相关联的键组成,通过键来检索值。
一个字典中不能有重复的键。
Dictionary<TKey, TValue>的容量是字典可以包含的元素数。当向字典中添加元素时,系统通过重新分配内部数组,根据需要自动增大容量。
该泛型类提供的常用方法如下。
Add方法:将带有指定键和值的元素添加到字典中。
TryGetValue方法:获取与指定的键相关联的值。
ContainsKey方法:确定字典中是否包含指定的键。
Remove方法:从字典中移除带有指定键的元素。

该泛型类提供的常用方法如下。
Add方法:将带有指定键和值的元素添加到字典中。
TryGetValue方法:获取与指定的键相关联的值。
ContainsKey方法:确定字典中是否包含指定的键。
Remove方法:从字典中移除带有指定键的元素。
下面的代码说明了字典的基本用法。

Dictionary<string, int> storedBooks = new Dictionary<string, int>
storedBooks . Add ("book1", 15);
storedBooks .Add ("book2", 25);
storedBooks .Add ( "book3", 5) ;
//输出字典中所有的书籍名称和存书数量
foreach (KeyValuePair<string, int> k in storedBooks)
{
	Console.writeLine ("Key={0},Value={1}", k.Key, k.Value);
}
//检查字典中是否存在mybook
if (!storedBooks . Conta insKey ("mybook"))
{
	storedBooks .Add ("mybook"30) ;
}
/ /输出book2中保存的数量
Console . WriteLine (storedBooks ["book2"]);
//如果存在book4,修改数量;如果不存在book4,将其添加到字典中
storedBooks ["book4"] = 20;
//如果存在book4,修改数量;如果不存在book4,将其添加到字典中
storedBooks ["book4"] = 20;
//获取book2的数量
int value = 0;
if (storedBooks. TryGetValue ("book2", out value)) 
{
	Console. WriteLine("\"book2\", value = {0}", value);
}
else
Console . WriteLine ("\"book2\"在字典中不存在") ; .
//如果存在book0,将其从字典中删除
storedBooks . Remove ("book0") ;

在这里插入图片描述

三、类和对象

在这里插入图片描述

概念

类是封装数据的基本单位,是一组具有相同数据结构和相同操作的对象的集合,用来定义对象可执行的操作(如方法、属性、事件等)。
我们将类的实例称为对象,一旦创建了一个对象,就可以调用对象的属性、方法和事件来访问对象的功能。
创建一个对象时,系统会自动为该对象分配内存,创建对象实际上做了两个方面的工作,一是使用new关键字要求系统分配内存,二是使用构造函数初始化数据。
销毁一个对象是采用垃圾回收机制来实现的,系统会在适当的时候自动启动回收机制,然后检测没有被引用的对象并将其销毁。实际上,销毁对象也是做了两个方面的工作, 一是释放对象占用的内存,二是将分配给对象的内存归还给堆( Heap)。
类和对象的区别可以用现实生活中的例子来说明。如果把汽车看成是一- 个类的话,则生活中的每一辆汽车都是一个对象,也可以说,每一辆汽车是汽车类的一 个实例。
在这里插入图片描述

创建

在C#语言中,使用class定义类,类结构为

[附加声明] [访问修饰符] class 类名称[: [基类] [, 接口序列]]
{
	[常量]:用来表示常数值
	[字段声明]:存储数据
	[属性]:保护数据
	[构造函数]:提供创建对象的方式,初始化类的数据成员
	[方法]:向类的外部提供某种功能
	[事件]
	...
}

其中,[]中的内容为可选项,号(:)后面表示被继承的类或者接口。
通常每个类都在一个独立的c# 源文件中
创建新的类意味着在当前项目中产生了种新的数据类型。

举例说明如何声明类、字段、构造函数和方法。

using System;
namespace ClassExample
{
	public class Child
	{
		//字段
		private int age;
		private string name;
		//不带参数的构造兩数
		public Child( )
		{
			name = "none";
			//带参数的构造函数
		}
		
		public Child (string name, int age)
		{
			this. name = name;
			this.age = age; .
		}
		//输出方法
		public void PrintChild( )
		{
			Console. writeLine("{0},{1} years old.", name, age) ;
		}
	}
	public class Program
	{
		public static void Main( )
		{
			//使用new关键字创建对象,new后是调用的构造函数
			Child childl = new Child("Zhang San", 11);
			Child child2 = new Child("Li Si", 10);
			Child child3 = new Child( );
			//显示结果
			Console. Write("Child #1: ");
			child1l . PrintChild( );
			Console. write("Child #2: ");
			child2. PrintChild( );
			Console. write ("Child #3: ");
			child3. PrintChild( );
			Console . ReadLine( );
		}
	}
}
输出结果:
Child #1: Zhang San, .
11 years old.
Child #2: Li Si, 10 years old.
Child #3: none, 0 years old.

常量

常量(constant) 是使用一个标识符来代替一个不变的值,如使用PI 代替圆周率。使用常量有两个好处:
一是使程序易于维护、修改;
二是使程序的安全性更好。
常量的类型
必须为sbyte、byte、 short、 ushort、 int、 uint、 long、 ulong、 char、 float. double、 decimal、
bool. string、 枚举类型或引用类型。在声明常量时,需要使用const 关键字。但是,常量必须在定义时就赋值。在定义完常量后,在后面的编程中就不允许对常量进行重新赋值。
【举例】下面声明名称为pi的、类型为float 的常量。

const float pi= 3.14f;/ /声明float类型的常量pi,并为它赋初值

如果使用一个const 关键字同时声明多个常量,那么常量之间需要使用“,”(逗号)分隔。

字段

字段表示类和对象中的数据成员。它是类中的变量。

【举例】下面声明两个字段: i和j。i字段没有显式被赋值,j字段显式被赋值
为20。

int 1;//声明一个字段1相配费
inti = 20;//声明一个字段并为它赋初值2008

根据字段的修饰方式,可以把字段分为以下4种。
静态字段:使用static修饰,对应于静态变量。
实例字段:不使用static修饰,对应于实例变量。
只读字段:使用readonly修饰。
易失字段:使用volatile修饰。该类型的字段很少使用,在此不做详细介绍。
【举例】下面在Program类中声明4个类型均为int 的字段: i、j、k和m。其中,
i为静态字段,它的值为20;
j为实例字段,它的值为100;
k为只读字段,它的值为1;
m为静态只读字段,它的值为15。

public class Program
static int i=20;      			//静态字段
int j=100;			   			//实例字段
readonly int k = 1;	   			//只读字段
static readonly int m = 15;		//静态只读字段

静态字段和实例字段最大的差别在于:静态字段不属于类的特定实例,而实例字段是属于其所在的实例,如i字段不属于Program类的某一个实例。

静态成员变量与实例成员变量的区别

静态成员变量属于类,类被加载时初始化,且只有一份。
实例成员变量属于对象,在每个对象被创建时初始化,每个对象一份。
静态成员变量的特点:存在优先于对象,被所有对象所共享,常驻内存。

实例的属于对象 静态的属于类。
当应用程序被编译时,编译器就会为应用程序的所有静态字段分配相应的存储位置。
因此,对于一个应用程序而言,每一个静态字段都只有一个存储位置。

方法

方法(method)表示类和对象中的操作。它是包含一系列语句的代码块,通过这些代码块能够实现预先定义的计算或操作。
方法一般声明在类或结构中,由访问级别、返回值、方法名称、方法参数和方法体组成。其中,访问级别、返回值、方法名称和方法参数统称
为方法的“签名”。方法参数包括在小括号“(”中,多个参数使用“,”(逗号) 分隔。
如果括号中为空,则表示该方法不需要参数。
[举例]下面在Program类中声明一个方法。该方法的签名为“public int Function
(int a,int b)”,方法名称为Function,访问级别为public, 返回值类型为int, 方法参数为“inta,intb”,方法体为紧跟该方法签名之后的两个“{}” 之间的代码。

using System;
namespace 示例 chapter8
{
	class Program
	{
		public int Function(int a, int b)//方法签名
		{
			
			return a + b;//方法体
			
		}
		static void Main(string[] args)
		{
			inti=2,j =3,k;
			Programp= new Program() ;
			kp.Function(1j) ;
			Console. WriteLine ("k="+k);
			Console. ReadLine() ;
		}
	}
}


运行结果:  k=5

方法参数

方法参数的使用可以提高代码的重用性。
方法参数可以包含一个或多个参数。如果存在多个参数,则参数之间使用逗号分隔。方法参数包括以下4种参数。
值参数:声明参数时不带任何修饰符,如int i等。
引用参数:声明参数时带有ref修饰符,如refint i等。
输出参数:声明参数时带有out修饰符,如out int i等。
参数数组:声明参数时带有params修饰符,如params int[] array等。

值参数
1.在栈中为形参分配空间

2.将实参的值复制给形参

一个值参数相当于一个局部变量,它的值来源于该方法调用时所提供的参数的值。

注意:在变量用作实参之前,变量必须被赋值。形参值改变,实参值不变。

引用参数
1.必须在方法的声明和调用中使用ref修饰符

2.实参必须是变量,在用作实参前必须被赋值。如果是引用类型的变量,可以赋值为一个引用或null;

引用参数不创建新的存储位置,而是使用其基础变量(作为方法参数的变量)的存储位置。
注意:在方法被调用时,引用参数也必须添加ref 关键字,且基础变量必须是明确赋值的。
注意:不会为形参在栈上分配内存,它们指向相同的内存位置。形参改变,实参也改变。

void MyMethod(ref int x)
{
    ...
}
int y=10;
MyMethod(ref y);
MyMethod(ref 10);//错误,必须是变量

输出参数
1.必须在方法的声明和调用中使用out修饰符

2.实参必须是变量。

3.可以返回多个结果

输出参数也不创建新的存储位置,而是使用其基础变量(作为方法参数的变量)的存储位置。
注意:在方法被调用时,输出参数也必须添加out关键字,且在方法返回之前, 必须为该参数明确赋值即要在方法内部赋值。(打破了return 返回一个值得局限)

输出参数与值参数的区别
1:方法内部必须为输出参数赋值

2;输出参数可以在传递之前不赋值

 static void MyMethod(out int x,out int y)
{
  x=10;
  y=20;
}
static void Main()
{
    int a,b;
    MyMethod(out a,out b);
    Console.WriteLine("a:{0},b:{1}",a,b);
}

参数数组
1.在参数列表中只能有一个参数数组,而且必须是列表中的最后一个。

2.参数数组的所有参数必须具有相同的数据类型。

3.在数据类型前使用params修饰符,在数据类型后放一组空的方括号。

void MyMethod(params int [] a)
{
  ...
}
void Main()
{
  MyMethod(1,2);
  MyMethod(1,2,3,4);
}

静态方法与实例方法

静态方法是类的方法,每个类也有自己的操作,静态方法从类一 创建好就开始存在。
而实例方法是对象的方法,只能通过对象去调用。
静态方法和实例方法与静态变量和实例变量比较相似,静态方法也是使用static 修饰符,而实例方法不使用static修饰符。静态方法输出某一个类,实例方法属于类的某一 个实例。
【举例】下面在Program类中声明两个方法: F1和F2。其中,F1为静态方法,
F2为实例方法。然后分别调用Program类的F1和F2。在调用F1方法时,直接使用Program类调用F1方法。
在调用F2方法时,首先为Program类创建一一个实例p,然后通过p实例调用F2方法。

using System;
namespace 示例 chapter8
{
	class Program
	{
		public static int F1 ()//静态方法F1
		{
			Console . WriteLine ("调用静态方法F1"); 
			return 1;
		}
		public int F2 ()//实例方法F2
		{
			 Console. WriteLine ("调用实例方法F2") ; 
			 return 2; 
		}
		static void Main(string[] args)
		{
			int r1= Program.F1() ;/ /调用Program类的静态方法F1
			Console. WriteLine("r1=+r1) ;
			Programp = new Program() ;
			int r2 =p.F2();//使用Program类的实例P调用实例方法F2
			Console. WriteLine ("r2="+r2);
			Console. ReadLine() ;
		}
	}
}
运行结果:
调用静态方法F1
r1=1
调用实例方法F2
r2=2

属性

属性
对字段起保护作用,可实现只读、只写功能。
本质就是对字段的读取与写入方法。
语法:

[访问修饰符]数据类型 属性名
get{ return 字段; }
set{字段= value; }

自动属性

[访问修饰符]数据类型 属性名{set;get;}

通常一个公有属性和一个私有字段对应。
属性只是外壳,实际上操作的私有字段。

public class Program
{
	private string name;//声明name字段
	public string Name//声明Name属性
	{
		get { return name;}//get访问器
		set { name = value;}//set访问器
	}	
	static void Main ()
	{
		Program P = new Program() ;
		p.Name一"This is a string."; //给P的属性Name赋值
		string name = p. Name;//调用p的属性Name
		Console. WriteLine (name) ;
		Console. ReadLine() ;
	}
}
运行结果为:
This is a string.

构造函数

构造函数是类的一种特定的方法,通常用来初始化新对象的数据成员,即设置数据成员的默认值。
构造函数是在创建给定类型的对象时执行的类方法,它的名称和其所属类的名称相同。在任何时候,只要创建类,就会调用它的构造函数。如果开发人员没有为类显式提供构造函数,则默认情况下C#编译器将为该类创建一个默认的无参构造函数
【举例】下面在A类中声明两个构造函数: public A和public A(int count)。第一个构造函数不携带任何参数,它也不执行任何操作。
第二个构造函数携带类型int的count参数,它用来初始化list数组,并设置该数组每一个元素的值。

public class A
{
	private string[] list;//元素类型为string的数组
	public A()//无参构造函数
	public A(int count)//构造函数
	{
		list = new string [count] ;//为list数组分配内存
	}
	for(int i= 0; i< count; i++)//为list数组的每一个元素赋值
	{
		list[i] = i. ToString();
	}
}

静态构造函数
类有一些静态字段或属性,需要在第一次使用类之前,从外部源中初始化这些静态字段和属性。因此,静态构造函数用于初始化类的静态成员。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。它也可以用于执行仅需执行一次的特定操作。
注意:静态构造函数是不可继承的,而且不能被直接调用。类的静态构造函数在给定应用程序城中至多执行一次,它要么在第一次创建类的实例时或第一次引用类的任何静态成员时被调用。

静态构造函数具有以下5个特点。
1.静态构造函数一般用 于初始化静态字段、只读字段的值。
2.静态构造函数既没有访问修饰符(它默认为私有的),也没有参数。声明静态构造函数时,需要添加static修饰符。
3.无法直接调用静态构造函数,也无法控制何时执行静态构造函数。
4.在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类。
5.如果类中包含Main{}方法,那么该类的静态构造函数将在调用Main{}方法之前执行。如果类包含任何带有初始值设定项的静态字段,则在执行该类的静态构造函数时,先要按照文本顺序执行那些初始值设定项。

this保留字

保留字this只能在实例构造函数、实例方法或实例访问器的块中使用,且表示当前实例。在类的方法中出现的this作为一个值类型,它表示对调用该方法的对象的引用。
但是,
在结构的构造函数中出现的this 作为-一个变量类型,它表示对正在构造的结构的引用。在结构的方法中出现的this作为一个变量类型,它表示对调用该方法的结构的引用。
注意:在结构中时,由于this 相当于一个变量,因此,可以对this赋值,甚至通过this可以修改其所属结构的值。

public class A
{
    int a;
    string b;
    public A(int a,sting b)
    {
        this.a=a;
        this.b=b;
     }
  }

四、结构

结构和类非常相似。类类型是一种引用类型,它的变量仅仅包含访问某个数据的一个引用(或地址)。但结构是一种值类型, 并且不需要堆分配。
如果声明一个很大的数组,为了引用每个对象,就需要分配更多的内存。在这种情况下,使用结构可以节约资源。
声明:

public struct Str//声明一个名为Str的结构体
{
	...结构体的语句已省略
}

结构的成员与类的成员相似;
结构和类的区别
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值