网站开发具体工作有那些,公司标志logo设计免费,学生网页设计主题,企业查询宝官网总目录 文章目录总目录前言一、C#简述1 C#是什么#xff1f;2 .Net平台3. C# 和.Net的关系4. 集成开发环境#xff08;IDE#xff09;二、控制台应用程序1. 常用代码2.注意事项三、基础语法1.编写C#代码注意事项2.C#注释2. 变量标识符关键字4. 变量#xff0c;字…总目录 文章目录总目录前言一、C#简述1 C#是什么2 .Net平台3. C# 和.Net的关系4. 集成开发环境IDE二、控制台应用程序1. 常用代码2.注意事项三、基础语法1.编写C#代码注意事项2.C#注释2. 变量标识符关键字4. 变量字段和属性的区别5.数据类型1、值类型2、引用类型3、指针类型6. 类型转换1、隐式转换2、显式转换3、装箱与拆箱7. 常量8. 运算符1、算数运算符2、关系运算符3、逻辑运算符4、位运算符5、赋值运算符6、其他运算符7、运算符优先级9. 流程控制语句1、选择结构2、循环(loop)结构10. 数组字符串结构体枚举11. C#关键字之修饰符1、访问修饰符2、其他修饰符11. 方法12. 类1、类的基本内容2、构造函数3、析构函数终结器4、内部类13. 接口14. 接口和抽象类结语前言
本文主要供自身复习使用主要内容就是将C#基础知识进行大纲式针对性的梳理。 一、C#简述
1 C#是什么
C# 是由微软Microsoft开发的一个简单的、现代的、通用的、面向对象的编程语言。
2 .Net平台
1 .Net框架.Net Framework 说到C#那就必须说说.Net C# 是 .Net 框架的一部分且用于编写 .Net 应用程序。 .Net Framework是一个平台主要可以开发Windows 桌面程序和Web应用。.Net 框架由一个巨大的代码库组成用于 C# 等客户端语言。 我们常见的.Net 框架的组件 公共语言运行库Common Language Runtime - CLR.Net 框架类库.Net Framework Class Library公共语言规范Common Language Specification通用类型系统Common Type System元数据Metadata和组件AssembliesWindows 窗体Windows FormsASP.Net 和 ASP.Net AJAXADO.NetWindows 工作流基础Windows Workflow Foundation - WFWindows 显示基础Windows Presentation FoundationWindows 通信基础Windows Communication Foundation - WCFLINQ 2 .Net Core .Net Core是微软继.Net Framework之后推出的可以跨平台的平台可以用来创建运行在mac、Linux上的应用程序 3 .Net 完成了对.Net Framework和.Net Core的整合是一个全新的强大的跨平台的平台
3. C# 和.Net的关系
.net就像是大舞台C#就是其中的一个演员演员可以使用平台提供的话筒wpf,用来唱歌创建应用程序也可以使用平台提供的舞池web跳舞创建web应用C#只可以在这个大舞台上展示但是这个舞台除了可以提供C#这个演员展示还可以提供C、Visual Basic、Jscript、COBOL 等演员展示
4. 集成开发环境IDE
目前主要使用的是Visual Studio 2022 (VS)
二、控制台应用程序
1. 常用代码
控制台应用程序是入门级的应用程序一般常用的代码如下
//输出
Console.Write();
//换行输出
Console.WriteLine();
//以上代码主要用于在控制台输出信息//读取输入
Console.Read();
//读取当前行输入
Console.ReadLine();
//读取字符
Console.ReadKey();
//以上代码主要用于在控制读取输入的信息//接受用户输入的字符串以换行结束
string sConsole.ReadLine();2.注意事项
控制台应用程序代码需要以Console.ReadLine()或Console.ReadKey()等结束否则代码走完控制台的窗体就会关闭
三、基础语法
1.编写C#代码注意事项
C#代码是区分大小写的所有的语句和表达式必须以分号;结尾。
2.C#注释
//表示单行注释/* */ 表示多行注释区域性注释
#region 区域注释名称Console.WriteLine(区域性的注释);
#endregion2. 变量标识符关键字
先看如下示例代码 class Rectangle{// 成员变量double length;double width;public double GetArea(){length 3;width 2;return length * width;}public void Display(){Console.WriteLine($Length: {length});Console.WriteLine($Width: {width});Console.WriteLine($Area: {GetArea()});}}变量变量是类的属性或数据成员用于存储数据。如上面案例代码中 length 和 width 就是成员变量标识符标识符是用来识别类、变量、函数或任何其它用户定义的对象 标识符命名规则 标识符必须以字母、下划线或 开头后面可以跟一系列的字母、数字 0 - 9 、下划线 _ 、。标识符中的第一个字符不能是数字。标识符必须不包含任何嵌入的空格或符号比如 ? - ! # % ^ * ( ) [ ] { } . ; : ’ / \。标识符不能是 C# 关键字。除非它们有一个 前缀。 例如if 是有效的标识符但 if 不是因为 if 是关键字。标识符必须区分大小写。大写字母和小写字母被认为是不同的字母。不能与C#的类库名称相同。 如上面的length、width、GetArea、Display 等变量或函数的名称都是标识符
关键字关键字是 C# 编译器预定义的保留字。这些关键字不能用作标识符但是如果您想使用这些关键字作为标识符可以在关键字前面加上 字符作为前缀。‘
4. 变量字段和属性的区别
首先我们写一个示例代码 class UserInfo{private string _id;private string _name;public string Id{get { return _id; }set { _id value; }}public string Name{get { return _name; }set { _name value; }}}上面的代码中_id_name 是字段IdName 是属性而_id_nameIdName都是成员变量。
字段和属性都是变量只不过是为了区分和数据安全做出了区分。字段和属性是相对于类而言的都是在类中定义的而变量不局限在类中可以定义在任何需要的地方字段一般使用在类的内部只可在当前类内部访问属性一般供外部类访问字段一般来讲都是private而属性则是对字段使用get和set 进行了封装一般为public字段值可以用作ref、out参数而属性不能
5.数据类型
在C#中有以下几种类型
值类型引用类型指针类型不常用
1、值类型
值类型变量可以直接分配给一个值。它们是从类 System.ValueType 中派生的。值类型直接包含数据。 值类型又可分为
分类详情备注整型byte short ushort int uint long ulong浮点型float double decimaldecimal多用于金钱计算上字符型char每个字符背后都对应着一个ascii码“A”为65“a”为97“0”为 48布尔型booltrue/false可以为空的值类型如 int?值为 null 的其他所有值类型的扩展结构体struct枚举enum元组值类型形如 double,intt1(1.1,2);详见C#元组的使用
2、引用类型
引用类型不包含存储在变量中的实际数据但它们包含对变量的引用。换句话说它们指的是一个内存位置。使用多个变量时引用类型可以指向一个内存位置。如果内存位置的数据是由一个变量改变的其他变量会自动反映这种值的变化。内置的 引用类型有object、dynamic 和 string。
分类详情备注对象类型Object对象Object类型 是 C# 通用类型系统Common Type System - CTS中所有数据类型的终极基类数组集合用户定义的类、接口、委托object动态类型Dynamic您可以存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。动态类型与对象类型相似但是对象类型变量的类型检查是在编译时发生的而动态类型变量的类型检查是在运行时发生的。字符串类型String字符串String类型 允许您给变量分配任何字符串值这里需要注意的就是转义符的使用
string相关的还有如下一个问题“\”的使用与扩展
运用详情备注\输出特殊字符使用在字符串中使用\则可以输出“”和\ 等字符\n换行使用在字符串中输出的时候会自动换行\t制表符使用在字符串中输出的时候会自动对齐隔开\b去掉上一个字符串如果需要输出\b则需进行转义
和\的使用
string path1 E:\\MyCode\\my-study;
string path2 E:\MyCode\my-study;
Console.WriteLine($path1:{path1}-------path2:{path2});由上可知当前我们使用进行字符串转义的话我们可以避免使用“\”逐个的进行转移。
3、指针类型
指针类型变量存储另一种类型的内存地址。C# 中的指针与 C 或 C 中的指针有相同的功能。 声明指针类型的语法type* identifier; 如char* cptr; int* iptr;
6. 类型转换
类型转换就是将数据从一种类型转换为另一种类型类型转换有两种形式
1、隐式转换
这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失。将类型较小的数据存放到较大的变量中
2、显式转换
显式转换需要强制转换运算符而且强制转换会造成数据丢失。将类型较大的数据存放在较小的变量中
案例代码如下 static void Main(string[] args){int num1 1;long num2 num1;//隐式类型转换//强制类型转换(数据类型)数据double num3 3.56;int num4 (int)num3;int num5 Convert.ToInt32(num3);//Convert 对象转换Console.WriteLine($3.56强制转换后的结果{num4}\n3.56使用Convert对象转换的结果{num5});Console.ReadLine();}由上面的代码案例可以清晰的了解数据的转换另外还可从上面的案例可知显式转换存在两种形式一种是强制类型转换这种方式对于浮点型不会进行四舍五入直接将小数点后面的数据舍弃另一种是使用Convert对象进行转换这种方式则会对浮点型数据进行四舍五入的计算然后进行转换。
3、装箱与拆箱 装箱是将值类型转换为引用类型 拆箱就是将引用类型转换为值类型 示例代码如下 static void Main(string[] args){//装箱值类型转换为引用类型int num 111;object obj num;Console.WriteLine($obj {obj}); //obj 111//拆箱引用类型转换为值类型int nnum 222;object oobjnnum;int result (int)oobj;Console.WriteLine($result {result});//result 222//【注意】被装过箱的对象才能被拆箱}我们知道平常写代码的时候要尽量的避免装箱和拆箱但是为什么要这样呢要搞清白这些啊那就必须知道什么是堆和栈以及装箱和拆箱的过程
堆和栈 堆栈简单来说就是计算机存储数据的一个数据模型。 模型分为堆和栈两部分栈中主要存放一些简单结构的数据和复杂数据的索引堆中存储复杂数据结构的数据内容。简单的数据结构就是值类型复杂数据结构就是引用类型 装箱和拆箱的过程 装箱过程 ①先在堆上为新生成的引用对象分配内存 ②然后将值类型的数据copy到刚分配的内存中 ③最后返回内存的地址引用对象在栈中会存储这个内存的地址相当于数据的索引。 在装箱的过程中分配内存和数据复制都是消耗效能的操作 拆箱过程 ①先检查当前的引用类型数据是否可以转换为目标值类型数据 例如string str123可以转换为Int ,而strasd不可以 ②复制堆中的数据的值并将复制的值放到目标数据所在的存储位置 拆箱过程有类型检查和复制数据两个操作其中复制数据耗费性能 由此我们可知装箱和拆箱比较影响程序运行的性能所以我们需要尽量的避免此类操作
7. 常量
常量是固定值程序执行期间不会改变。常量可以是任何基本数据类型比如整数常量、浮点常量、字符常量或者字符串常量还有枚举常量。 常量可以被当作常规的变量只是它们的值在定义后不能被修改。
详情可见C#常量这里重点说一下定义常量常量是使用const关键字来定义的示例如下 public const string URL www.xxxx.com;public const int num 999;常量扩展 静态常量编译时常量const 和动态常量运行时常量readonly 静态常量在编译时就确定了值必须在声明时就进行初始化且之后不能进行更改可在类和方法中定义。定义方法如下
const double a3.14// 正确声明常量的方法
const int b; // 错误没有初始化动态常量在运行时确定值只能在声明时或构造函数中初始化只能在类中定义。定义方法如下
class Program
{readonly int a1; // 声明时初始化readonly int b; // 构造函数中初始化Program(){b2;}static void Main(){}
}8. 运算符
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C# 有丰富的内置运算符分类如下
算术运算符关系运算符逻辑运算符位运算符赋值运算符其他运算符
1、算数运算符
运算符描述备注将两个操作数相加当字符串和数值类使用 则是拼接字符串-将两个操作数相减*将两个操作数相乘/将两个操作数相除当两个操作数均为整数的时候结果取商当两边有一个为浮点型的时候做精确运算%模运算符整除后取余数如 21%101自增运算符整数值增加1注意当自增运算符在前则先自增然后再使用自增后的赋值当自增运算符在后则先赋值然后再自增- -自减运算符整数值减去1同上
注意在char类型参与到算数运算时会自动转化为ascii码10进制的值参与运算
class Program{static void Main(string[] args){int a 1;int b;// a 先赋值再进行自增运算b a;Console.WriteLine(a {0}, a);Console.WriteLine(b {0}, b);Console.ReadLine();//结果a2,b1// a 先进行自增运算再赋值a 1; // 重新初始化 ab a;Console.WriteLine(a {0}, a);Console.WriteLine(b {0}, b);Console.ReadLine();//结果a2,b2// a-- 先赋值再进行自减运算a 1; // 重新初始化 ab a--;Console.WriteLine(a {0}, a);Console.WriteLine(b {0}, b);Console.ReadLine();//结果a0,b1// --a 先进行自减运算再赋值a 1; // 重新初始化 ab --a;Console.WriteLine(a {0}, a);Console.WriteLine(b {0}, b);Console.ReadLine();//结果a0,b0}}2、关系运算符
运算符描述检查两个操作数的值是否相等如果相等则条件为真!检查两个操作数的值是否相等如果不相等则条件为真。检查左操作数的值是否大于右操作数的值如果是则条件为真检查左操作数的值是否小于右操作数的值如果是则条件为真。检查左操作数的值是否大于或等于右操作数的值如果是则条件为真。检查左操作数的值是否小于或等于右操作数的值如果是则条件为真。
注关系运算符的运算结果均是bool 常运用于判断语句中
3、逻辑运算符
运算符描述||或 运算符当两个操作数均为false ,则结果为false,其余均为true与 运算符, 当两个操作数均为true,则结果为true,其余均为false!非 运算符取反
注 ① 逻辑运算符的短路效果当运算符的左边的结果对整个表达式结果起了决定性的作用的时候运算符右边的表达式就不会运行。 如当运算符左边为false的时候此时无论运算符右边是什么结果都为false,那么右边表达式就不会运行。 ② 当单独使用| 和 就不会产生短路的效果即使左边已经起了决定性作用右边仍会运行。
4、位运算符 运算符描述与 位运算符当两个操作数均为1 ,则结果为1,其余均为0|或 位运算符, 当两个操作数均为0,则结果为0,其余均为1^异或 运算符当两个操作均为0或1则结果为0其余结果为1~按位取反 运算符具有翻转位的效果可将0变11变0二进制左移运算符。左操作数的值向左移动右操作数的位数二进制右移运算符。左操作数的值向右移动右操作数指定的位数。
辅助理解的案例代码如下 static void Main(string[] args){//60 和13 转换位二进制分别是111100 和 1101 不足8位【前面】使用0补足int a 60; /* 60 0011 1100 */int b 13; /* 13 0000 1101 */int c 0;c a b;// a 0011 1100// b 0000 1101//----------------- 根据运算符规则只有均为1的时候结果才为1否则均为0// c 0000 1100转换为十进制 则是12Console.WriteLine(Line 1 - c 的值是 {0}, c);c a | b;// a 0011 1100// b 0000 1101//----------------- 根据|运算符规则只有均为0的时候结果才为0否则均为1// c 0011 1101转换为十进制 则是61Console.WriteLine(Line 2 - c 的值是 {0}, c);c a ^ b;// a 0011 1100// b 0000 1101//----------------- 根据^运算符规则只有均为0或1的时候结果才为0否则均为1// c 0011 0001转换为十进制 则是49Console.WriteLine(Line 3 - c 的值是 {0}, c);c ~a; /*-61 1100 0011 */// a 0011 1100//取反----------------- 根据~运算符规则将0变1 1变0// c 1100 0011转换为十进制 则是-61Console.WriteLine(Line 4 - c 的值是 {0}, c);c a 2; // a 0011 1100//左移----------------- 0011 1100 向左移动两位则将前面两位00 移掉了然后后面补足两位00// c 1111 0000转换为十进制 则是240Console.WriteLine(Line 5 - c 的值是 {0}, c);c a 2;// a 0011 1100//右移----------------- 0011 1100 向右移动两位则将后面两位00 移掉了然后前面补足两位00// c 0000 1111转换为十进制 则是15Console.WriteLine(Line 6 - c 的值是 {0}, c);Console.ReadLine();}5、赋值运算符 6、其他运算符
这里包括有 is,as ,?: 等运算符会在后续专题博客中详细介绍这里暂时不做展开~
7、运算符优先级
优先级大体上是算数运算符 关系运算符逻辑运算符赋值运算符算数运算中当有括号时先计算括号内的然后前运算符再乘除模再加减最后后运算符逻辑运算符中当同时出现或运算符和与运算符先计算与 运算符然后计算或运算符
辅助理解的案例代码如下
//算术运算符和赋值运算符的优先级
int a 10, b 5, c 2;
a b * c; // 先计算乘法再执行加法赋值
Console.WriteLine(a); // 输出20//逻辑运算符的优先级
bool a true, b false, c true;
bool result a || b c; // 先计算与运算再计算或运算
Console.WriteLine(result); // 输出true//条件运算符的优先级
int a 10, b 5;
string result a b ? a大于b : a不大于b; // 先判断大小关系再执行条件语句
Console.WriteLine(result); // 输出a大于b
9. 流程控制语句
1、选择结构
if else //第一种只有if,没有elseif (num15){//...}//第二种有if elseif (num 15){//...}else{//...}//第三种多种判断if else if ...elseif (num15){//...}else if (num0){//...}else{//...}switch
一个 switch 语句允许测试一个变量等于多个值时的情况算是if else 在某一层面上的进阶版。
switch 语句中的表达式 必须是一个整型或枚举类型或者是一个 class 类型其中 class 有一个单一的转换函数将其转换为整型或枚举类型
运用switch的典型案例输入年月得出该月的天数 static void Main(string[] args){Console.WriteLine(请输入年份);int year Convert.ToInt32(Console.ReadLine());Console.WriteLine(请输入月份);int month Convert.ToInt32(Console.ReadLine());int day 0;//定义天数switch (month){//大月case 1:case 3:case 5:case 7:case 8:case 10: case 12: day 31; break;//小月case 4: case 6: case 9: case 11: day 30; break;case 2://主要是需要对二月进行判断是否是闰月if (year % 4 0 year % 100 ! 0 || year % 400 0){//满足条件则为闰年中的闰月输出29天day 29;break;}else{day 28;break;}default:Console.WriteLine(请输入正确的月份数字);break;}Console.WriteLine(${year}年{month}月有{day}天);Console.ReadLine();}三元运算符?:
x?y:z 表示如果表达式 x 为 true则返回 y如果 x 为 false则返回 z是 if{}else{} 的简单形式。 static void Main(string[] args){int a11; int b22;int c a b ? a : b;Console.WriteLine($c{c});Console.ReadLine();//结果: c22}2、循环(loop)结构
循环语句允许我们多次执行一个语句或语句组。
for
简单使用案例 for (int i 0; i 10; i){Console.WriteLine($i{i});}Console.ReadLine();当我们需要无限循环的时候只需要如下使用 //将各项条件均省略程序会默认为true,一直运行for (; ;){Console.WriteLine(我是无限循环);}常见题目百钱百鸡兔子生小兔子斐波拉且数列,猜价格价格截半法 static void Main(string[] args){//某人有100元钱要买100只鸡。//公鸡5元钱一只母鸡3元钱一只小鸡一元钱3只。//编程计算可买到公鸡母鸡小鸡各为多少只//首先从循环次数上将从公鸡开始循环次数最少//首先100元最多买20只公鸡,for (int i 0; i 20; i)//i为公鸡数 {//j为母鸡数for (int j 0; j 33; j){if ((100-i-j)%30i*5j*3(100-i-j)/3100){Console.WriteLine($公鸡{i},母鸡{j},小鸡{100-i-j});}}} Console.ReadLine();}static void Main(string[] args){//程序循环猜商品价格//首先定义价格范围int max 1000;int min 1;//定义随机数Random rnd new Random();//定义一个标记一会使用goto重新从标记位执行代码方便测试使用Flag://随机一个正确价格int correctPrice rnd.Next(min,max1);Console.WriteLine($正确价格是{correctPrice});//开始猜价格for (int i 1;; i){int price (min max) / 2;if (correctPrice price){Console.WriteLine($第{i}次猜测的价格{price}低了);min price 1;}else if (correctPrice price){Console.WriteLine($第{i}次猜测的价格{price}高了);max price - 1;}else{Console.WriteLine($恭喜你第{i}次猜测的价格{price}正确);break;}}if (Console.ReadKey().KeyCharA){min 1;max 1000;goto Flag;}Console.ReadLine();}注意理解案例中的for循环的运用以及价格截半的精髓二分查找另外案例中有个goto关键字的运行和使用
foreach
使用foreach可以迭代数组或者一个集合对象。 static void Main(string[] args){string[] arrStr new string[] { ab, cd, ef };foreach (var item in arrStr){Console.WriteLine($遍历数组-当前项{item});}Console.ReadLine();}foreach 迭代遍历只能是正向的不可逆的逐个的遍历数组中的每一个元素迭代遍历时被迭代的数组的元素不能更改迭代遍历的速度远快于for循环。
while 和do…while
简单使用案例 static void Main(string[] args){/* 局部变量定义 */int a 10;/* while 循环执行 */while (a 20)//只要条件为true,也可无限循环下去{Console.WriteLine(a 的值 {0}, a);a;}Console.ReadLine();}static void Main(string[] args){/* 局部变量定义 */int a 10;/* do 循环执行 */do{Console.WriteLine(a 的值 {0}, a);a;} while (a 20);Console.ReadLine();}先执行do然后判断while的条件当条件为true的时候才进入循环相较于while循环do…while无论是否满足循环条件都会先执行一次业务代码。
循环控制语句
循环控制语句更改执行的正常序列。当执行离开一个范围时所有在该范围中创建的自动对象都会被销毁
控制语句描述break终止 loop 或 switch 语句程序流将继续执行紧接着 loop 或 switch 的下一条语句。简单说在loop中使用break将跳出整个循环continue跳出本轮循环,开始下一轮循环
10. 数组字符串结构体枚举
1、数组 数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合通常认为数组是一个同一类型变量的集合。 数组中重要的三个组成部分就是元素数组中的每一项都是一个元素长度数组的长度索引从0开始
使用案例 //声明数组int[] nums;//初始化数组double[] scoresnew double[10];//赋值给数组--逐个元素赋值double[] doublesnew double[10];doubles[0] 10.1;doubles[1] 10.2;//初始化并赋值给数组,可省略数组长度double[] doubles1 new double[]{10.1,10.2 };//简化赋值过程double[] doubles2 { 10.1, 10.2, 10.3 };//访问数据元素,通过索引double num doubles2[0];//不过大多时候都是使用for 和foreach 来操作数据for (int i 0; i doubles2.Length; i){Console.WriteLine($元素doules[{i}]{doubles2[i]});}Console.ReadLine();数组扩展内容见C#数组详解
2、字符串 在 C# 中您可以使用字符数组来表示字符串但是更常见的做法是使用 string 关键字来声明一个字符串变量。string 关键字是 System.String 类的别名。 关于字符串的详细内容可见C#字符串使用详解
3、结构体 在 C# 中结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。struct 关键字用于创建结构体。 结构体特点如下 结构可带有方法、字段、索引、属性、运算符方法和事件。结构可定义构造函数但不能定义析构函数。但是您不能为结构定义无参构造函数。无参构造函数(默认)是自动定义的且不能被改变。与类不同结构不能继承其他的结构或类。结构不能作为其他结构或类的基础结构。结构可实现一个或多个接口。结构成员不能指定为 abstract、virtual 或 protected。当您使用 New 操作符创建一个结构对象时会调用适当的构造函数来创建结构。与类不同结构可以不使用 New 操作符即可被实例化。如果不使用 New 操作符只有在所有的字段都被初始化之后字段才被赋值对象才被使用。 另外结构体与类的区别 类是引用类型结构是值类型。结构不支持继承。结构不能声明默认的构造函数。结构体中声明的字段无法赋予初值类可以:结构体的构造函数中必须为结构体所有字段赋值类的构造函数无此限制:
代码如下
using System;
using System.Text;struct Books
{private string title;//结构体中声明的字段无法赋予初值类可以:private string author;private string subject;private int book_id;public void setValues(string t, string a, string s, int id){title t;author a;subject s;book_id id;}public void display(){Console.WriteLine(Title : {0}, title);Console.WriteLine(Author : {0}, author);Console.WriteLine(Subject : {0}, subject);Console.WriteLine(Book_id :{0}, book_id);}}; public class testStructure
{public static void Main(string[] args){Books Book1 new Books(); /* 声明 Book1类型为 Books */Books Book2 new Books(); /* 声明 Book2类型为 Books *//* book 1 详述 */Book1.setValues(C Programming,Nuha Ali, C Programming Tutorial,6495407);/* book 2 详述 */Book2.setValues(Telecom Billing,Zara Ali, Telecom Billing Tutorial, 6495700);/* 打印 Book1 信息 */Book1.display();/* 打印 Book2 信息 */Book2.display();Console.ReadKey();}
}4、枚举 枚举是一组命名整型常量。枚举类型是使用 enum 关键字声明的。 C# 枚举是值类型。换句话说枚举包含自己的值且不能继承或传递继承。
枚举是值类型的数据只能定义值类型的内容枚举是将值进行包装enum 默认自带public static ,无需实例化enum和int的值是相互参照的enum中的值与int转换的时候默认按照012的顺序排序也可以自行定义enum中每一项枚举的值
使用案例如下 //声明enum变量,不定义各项的值默认enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat };//声明enum变量,自定义各项的值enum Day{Sun 10,Mon 20, Tue 30, Wed 40, Thu 50, Fri 60, Sat 70,}//混合情况,第 n 个符号值与第 n-1 个有关如此时Mon为 11enum WeekDay{Sun 10, Mon, Tue, Wed 40, Thu, Fri, Sat,}class Program{static void Main(string[] args){//默认情况下枚举中的值与int相互转换从0开始依次增加int x (int)Days.Sun;int y (int)Days.Fri;Console.WriteLine(Sun {0}, x);//Sun 0Console.WriteLine(Fri {0}, y);//Sun 5Day day (Day)20;//将int值转化为枚举Console.WriteLine(day.ToString());//将枚举转换成字符串结果Mon//将字符串转化为枚举Day day1 (Day)Enum.Parse(typeof(Day), Mon);//如果Mon在不在枚举内这种情况下会报错//混合情况,第 n 个符号值与第 n-1 个有关。int dy (int)WeekDay.Mon;int dx (int)WeekDay.Tue;int dz (int)WeekDay.Sat;Console.WriteLine(WeekDay\tMon {0}, dy);//WeekDay Mon 11Console.WriteLine(WeekDay\tTue {0}, dx);//WeekDay Tue 12Console.WriteLine(WeekDay\tSat {0}, dz);//WeekDay Sat 43Console.ReadLine();}}关于枚举的进阶用法详情可见C#枚举进阶用法
11. C#关键字之修饰符
C#中的修饰符都是关键字
1、访问修饰符
C# 封装根据具体的需要设置使用者的访问权限并通过 访问修饰符 来实现。 一个 访问修饰符 定义了一个类成员的范围和可见性。
protected internal 是 protected 和 internal 的并集满足任何一个即可可访问性排序public internal protected private 2、其他修饰符
常用修饰符还有 static、abstract、virtual、override、sealed、readonly、extern、event、const、async、in、new、out 不常用的修饰符有unsafe、volatile
这里会对部分修饰符的使用进行整理汇总其余部分如果在后续深入的过程中涉及到也会逐步整理出来
static 静态的 使用 static 修饰符可声明属于类型本身而不是属于特定对象的静态成员。 static 修饰符可用于声明 static 类。 在类、接口和结构中可以将 static 修饰符添加到字段、方法、属性、运算符、事件和构造函数。 static 修饰符不能用于索引器或终结器。 如果 static 关键字应用于类则类的所有成员都必须为 static。 程序默认就创建实例因此static对象无需实例化直接使用 类中静态变量它只是定义在当前类中但是本身不属于类它早已经实例化因此调用的时候直接使用类名 点.运算符进行调用 使用过多的静态对象会比较消耗内存因为它默认就实例化了已经占好了内存 使用案例如下 class UserInfo{private string _id;//静态变量public static string Info;//普通变量public string Id{get { return _id; }set { _id value; }}}class Program{static void Main(string[] args){//使用静态变量无需实例化直接通过类名.string info UserInfo.Info;//使用普通变量,需要先实例化才可以string id new UserInfo().Id;Console.ReadLine();}}abstract 抽象的 abstract 修饰符可用于类、方法、属性、索引和事件 抽象方法 抽象方法是隐式的虚拟方法abstract方法默认自带virtual属性 只有抽象类中才允许抽象方法声明。 由于抽象方法声明不提供实际的实现因此没有方法主体方法声明仅以分号结尾且签名后没有大括号 ({ })。 在抽象方法声明中使用 static 或 virtual 修饰符是错误的。 抽象方法如下
public abstract void GetInfo();//实现由方法 override 提供它是非抽象类的成员。 抽象类 抽象类不能实例化。 必须有子类继承 派生自抽象类的非抽象类必须包含全部已继承的抽象方法和访问器的实际实现。 简单说子类必须实现抽象父类的所有抽象方法 在抽象方法声明中使用 static 或 virtual 修饰符是错误的。 sealed 封闭的 通常用于实现第三方类库时不想被客户端继承或用于没有必要再继承的类以防止滥用继承造成层次结构体系混乱。恰当的使用sealed修饰符也可以在一定程度上提高运行效率因为不用考虑继承类会重写该成员。 sealed的作用 在类声明中使用sealed可防止其它类继承此类 在方法声明中使用sealed修饰符可防止子类重写此方法。 sealed修饰符主要用于防止非有意的派生但是它还能促使某些运行时优化 密封类中永远不可能有任何派生类。如果密封类实例中存在虚拟成员函数该成员函数可以转化为非虚的函数修饰符virtual 不再生效。 11. 方法
首先在C#中对于函数和方法并没有明确的定义区分本质上是一样的只是叫法不同某些情况下如我们会更习惯叫构造函数而不叫构造方法。
熟悉方法无非两点定义方法和调用方法。 定义方法
Access Specifier Return Type Method Name(Parameter List)
{Method Body
}访问修饰符 方法修饰符 返回类型 函数名( 参数列表 )
{函数体;
}//实例如下
public void GetInfo(string id)
{//....
}调用方法 调用通过方法名调用方法如
Rectangle rectangle new Rectangle();
//Display即是矩形对象中的方法通过方法名调用即可
rectangle.Display();12. 类
1、类的基本内容
当你定义一个类时你定义了一个数据类型的蓝图。构成类的方法和变量称为类的成员。访问标识符 指定了对类及其成员的访问规则。如果没有指定则使用默认的访问标识符。类的默认访问标识符是 internal成员的默认访问标识符是 private。如果要访问类的成员你要使用点.运算符。点运算符链接了对象的名称和成员的名称。
2、构造函数
类的 构造函数 是类的一个特殊的成员函数当创建类的新对象时执行。构造函数提供了一种对象的多种创建方式。构造函数的名称与类的名称完全相同它没有任何返回类型。
认识一下构造函数代码如下 class Student{public string Name { get; set; }public double Score { get; set; }//构造函数没有任何返回类型public Student(){}}构造函数分为默认/隐式构造函数 和参数化构造函数
默认构造函数没有参数列表没有代码默认隐藏不显示有且仅有一个参数化构造函数手工定义只要参数列表不同可以有N个如果类中定义了一个参数化的构造函数默认会把隐式的构造函数替换掉如果需要支持或者用到 无参数的构造函数就需要定义起来 class Student{public string Name { get; set; }public double Score { get; set; }//默认构造函数没有任何返回类型public Student(){}//参数化构造函数public Student(string name){}//参数化构造函数public Student(string name, double score){}}3、析构函数终结器
终结器以前称为析构函数用于在垃圾回收器收集类实例时执行任何必要的最终清理操作。 在大多数情况下通过使用 System.Runtime.InteropServices.SafeHandle 或派生类包装任何非托管句柄可以免去编写终结器的过程。
无法在结构中定义终结器。 它们仅用于类。一个类只能有一个终结器。不能继承或重载终结器。不能手动调用终结器。 可以自动调用它们。终结器不使用修饰符或参数。
class Car
{~Car() // finalizer{// cleanup statements...}
}public class Destroyer
{public override string ToString() GetType().Name;~Destroyer() Console.WriteLine($The {ToString()} finalizer is executing.);
}不应使用空终结器。 如果类包含终结器会在 Finalize 队列中创建一个条目。 此队列由垃圾回收器处理。 当 GC 处理队列时它会调用每个终结器。 不必要的终结器包括空的终结器、仅调用基类终结器的终结器或者仅调用条件性发出的方法的终结器会导致不必要的性能损失。 程序员无法控制何时调用终结器因为这由垃圾回收器决定。 垃圾回收器检查应用程序不再使用的对象。 如果它认为某个对象符合终止条件则调用终结器如果有并回收用来存储此对象的内存。 可以通过调用 Collect 强制进行垃圾回收但多数情况下应避免此调用因为它可能会造成性能问题。
4、内部类
顾名思义就是类中定义的类。 内部类的目的 是为了隐藏一个类中的类 保护内部的类
13. 接口
接口本身并不实现任何功能它只是和声明实现该接口的对象订立一个必须实现哪些行为的契约。接口更像是抽象方法的一个集合 interface IDataLink{void Contect();void DisContect();}1 抽象类是类可以定义变量有构造函数使用abstract 是禁止实例2 接口不是类里面可以定义变量但是必须赋值因为他只是抽象方法集合所以必须自己赋初始值 实例化3 接口中方法默认都是public abstract
14. 接口和抽象类
相同点
1、 都不能实例化2、 实现类 都必须实现所有抽象方法
不同点
1 接口是多重继承抽象类是单一继承2 一个类只能继承一个父类但是可以实现n个接口3 抽象类是类接口不是类抽象方法的集合
其余涉及到面向对象编程的内容如封装继承多态等将在下一篇博客中进行展开~ 结语
以上就是本文的内容希望以上内容可以帮助到您如文中有不对之处还请批评指正。 参考资料 C# 语言介绍 C#教程 装箱与拆箱