.net/dotnet:一般指.Net Framework框架.一种平台,一种技术
C#(sharp):一种编程语言,可以开发基于.net平台的应用
.net都能干什么?
桌面应用程序 Winform Internet应用程序 ASP.NET 手机开发 wp8 Unity3D游戏开发或者虚拟现实 .NET俩种交互模式
C/S:客户机(Client)/服务器模式(Server) winform应用程序 B/S:浏览器(Browser)/服务器模式(Server) Internet应用程序 1.1 开发工具:Visual Studio 新建项目:选择Visual C#->Windows->控制台应用程序,起一个英文名称(最好见名知意) 一个解决方案下可以有多个项目:解决方案右键->添加->新建项目
.cs结尾的称为类文件
解决方案资源管理器(视图里找)
Program组成部分
.sln: 解决方案文件,里面包含整个解决方案的信息,可以双击运行
.csproj: 项目文件,里面包含项目的信息,可以双击运行
1.2 C#基础 C#中,每行代码都以;
结束.
输出: Console.WriteLine("输出内容");
Console.ReadKey();
作用:暂停当前程序,等待用户按下任意键继续,按下的任意键将显示在控制台当中
vs快捷键:
Ctrl+K+D 快速对齐 Ctrl+S 保存 Ctrl+Z 撤销 Ctrl+J 提示 Ctrl+K+C 注释 Ctrl+K+U 取消注释 #region…#endregion 折叠代码 vs设置: 工具->选项(推荐将字体(环境->字体和颜色)改为Consolas)
启动项目设置: 解决方案右键->属性->启动项目改为当前选定内容
项目的加载与卸载: 右键需要修改的项目->移除/卸载(不可用,当需要时可以右键重新加载)
1.3 注释符 作用: 1.注销 2.解释
单行注释: //
多行注释: /* 注释内容 */
文档注释: ///
多用来解释类或者方法
1.4 变量 在计算机中存储数据
语法: 变量类型 变量名 = 值;
整数类型: int 只能存整数,不能存储小数
小数类型: double 既能存整数,也能存小数,小数点后位数 15 ~ 16位
字符类型不能为空,并且只能有一个 字符: char ch = 'a';
字符串类型可以存空,字符串: string name = "张三";
存钱: decimal money = 5000m;
后面需加上一个m
变量命名规则:
必须以字母下划线或"@"符号开头,不能以数字开头 后面可以跟任意字母、数字、下划线 不能更C#关键字重复 区分大小写 同一变量名不允许重复定义 变量命名必须有意义 Camel命名规则:除第一个单词第一个字母小写,其他每一个单词第一个字母大写(变量命名) Pascal命名规则:每一个单词第一个字母大写(类或者方法命名) 变量必须先声明,再赋值,最后再使用
1.5 赋值运算符 = 意义: 表示把等号右边的值赋值给等号左边的变量
"+"号作用: 1.连接俩个字符串 2.相加(俩个数字)
占位符 使用方法: 先挖个坑,再填
多填:没效果 少填:抛异常
输出顺序:按照挖坑的顺序
保留小数:
{:0.00}//保留俩位小数
1 2 3 4 5 6 int n1 = 10 ;int n2 = 20 ;int n3 = 30 ;Console.WriteLine("第一个数字:{0},第二个数字:{1},第三个数字:{2}" , n1, n2, n3); Console.ReadKey();
交换变量 交换变量: 1.设置中间变量temp 2.交换俩整型变量:n1=n1-n2;n2=n1+n2;n1=n2-n1;
1.6 输入 string str = Console.ReadLine();
1.7转义符 转义符指的是一个’’+一个特殊字符组成一个具有特殊意义的字符
\n:表示换行 \":表示一个英文半角的双引号 \t:表示一个Tab键的空格 \b:表示退格键,放字符串俩边无用 @: 1.取消\转义作用 2.将字符串按照原格式输出 \r\n:windows操作系统不认识\n,只认识\r\n \\:表示一个\
1.8 算术运算符 (二元运算符) 加(+)、减(-)、乘( * )、除(/)、取余(%)
1.9 显式类型转换和隐式类型转换 要求等号俩边参与运算的操作数的类型必须一致,如果不一致,满足下列条件会发生自动类型转换,或者称之为隐式类型转换
俩种类型兼容 目标类型大于原类型(eg:double>int) int — double 强制类型转换 double — int 显式类型转换 (eg:(int)double值)
语法: (待转换的类型)要转换的值
1.10 Convert类型转换 条件:
1 2 3 4 5 6 string s = "123" ;double d = Convert.ToDouble(s);int n = Convert.ToInt32(s);Console.WriteLine(d); Console.WriteLine(n); Console.ReadKey();
1.11 加加减减 (一元运算符) ++: 分为前++、后++,最终结果都为变量+1,不同的是前++是先+1再用+1后的值去运算,后++是先用原先的值参与运算再将这个变量+1 –: 同上
一元运算符优先级高于二元运算符
1.12 关系运算符和逻辑运算符 关系运算符: 大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、等于(==)、不等于(!=)
bool类型:
逻辑运算符: 逻辑与(&&)全真才真,一假就假、逻辑或(||)全假才假,一真就真、逻辑非(!)
&&优先级高于||
1.13 复合赋值运算符 +=、-=、*=、/=、%=
异常捕获: 1 2 3 4 5 6 try { 可能出异常的代码 }catch { 出异常执行代码 }
2 流程控制 循环结构:程序从Main函数进入,从上到下一行一行的执行,不会落下任意一行 分支结构:if if-else 选择结构:if else-if switch-case 循环结构:while do-while for foreach
2.1 if if: 语法: if(判断条件) { 要执行的代码; }
判断条件:一般为关系表达式或者bool类型的值
if-else: 语法: if(判断条件) { 条件成立执行的代码; }else{ 条件不成立执行代码; }
if else-if: 语法: if(判断条件1) { 条件1成立执行的代码; }else if(判断条件2) { 条件2成立执行的代码; }… else{ 条件都不成立执行代码; }
2.2 switch-case 作用: 用于处理多条件的定值的判断
语法: switch(变量或者表达式的值) { case 值1:要执行的代码; break; case 值2:要执行的代码; break; case 值3:要执行的代码; break; … default:要执行的代码; break; }
案例: 判断年份 案例描述: 输入年份和月份,输出对应的天数
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 using System;namespace 判断闰年{ class Program { static void Main (string [] args ) { Console.WriteLine("请输入一个年份" ); try { int year = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("请输入一个月份" ); try { int month = Convert.ToInt32(Console.ReadLine()); if (month >= 1 && month <= 12 ) { int day = 0 ; switch (month) { case 1 : case 3 : case 5 : case 7 : case 8 : case 10 : case 12 : day = 31 ; break ; case 2 : if ((year % 400 == 0 ) || (year % 4 == 0 && year % 100 != 0 )) { day = 29 ; } else { day = 28 ; } break ; default : day = 30 ; break ; } Console.WriteLine("{0}年{1}月有{2}天" , year, month, day); } else { Console.WriteLine("输入的月份不符合要求,程序退出" ); } } catch { Console.WriteLine("输入的月份有误,程序退出" ); } } catch { Console.WriteLine("输入的年份有误,程序退出" ); } Console.ReadKey(); } } }
2.3 while 语法: while(循环条件) { 循环体; }
break用法: 1.跳出switch-case结构 2.跳出当前循环 一般不单独使用,而是跟着if判断一起使用
特点:先判断,再执行,有可以一遍循环都不执行
2.4 do-while循环 语法: do { 循环体; }while(循环条件);
特点:先执行,再判断,至少执行一遍
断点调试 设置断点(在行号前点击空白处) 单步运行(F11逐语句调试) 观察变量(鼠标放在变量名上观察) F10逐过程调试 2.5 for循环 语法: for(表达式1;表达式2;表达式3) { 循环体4; }
表达式1:一般为声明循环变量,记录循环的次数(int i = 0;) 表达式2:一般为循环条件 表达式3:一般为改变循环条件的代码,使循环条件终会不成立,否则就是死循环
顺序:1->2->4->3->2->4->3->…
代码提示: 输入for,再按俩下Tab键
案例: 水仙花数 案例描述:输出三位数的水仙花数(水仙花数:每位数字的三次方的和等于原数字)
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 using System;namespace 水仙花数{ class Program { static void Main (string [] args ) { for (int i = 100 ; i <= 999 ; i++) { int bai = i / 100 ; int shi = i % 100 / 10 ; int ge = i % 10 ; if (bai*bai*bai+shi*shi*shi+ge*ge*ge==i) { Console.WriteLine("{0}\t" , i); } } Console.ReadKey(); } } }
2.6 for循环嵌套 案例: 九九乘法表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 using System;namespace 九九乘法表{ class Program { static void Main (string [] args ) { for (int i = 1 ; i <=9 ; i++) { for (int j=1 ;j<=i;j++) { Console.Write("{0}x{1}={2}\t" , j, i, i * j); } Console.WriteLine(); } Console.ReadKey(); } } }
2.7 类型转换 int.TryParse:尝试将一个字符串转换成int类型
eg:
1 2 3 4 5 6 7 int number = 0 ;bool b = int .TryParse("123" ,out number);Console.WriteLine(b); Console.WriteLine(number);
案例: 质数 案例描述: 找出100以内的所有质数(质数/素数:只能被1和本身整除的数字,比如:2)
提示: continue用法: 结束本次循环,判断循环条件,如果成立则进入下一次循环,否则退出循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 using System;namespace 质数{ class Program { static void Main (string [] args ) { for (int i=2 ;i<=100 ;i++) { bool b = true ; for (int j=2 ;j<i;j++) { if (i%j==0 ) { b = false ; break ; } } if (b) { Console.WriteLine(i); } } Console.ReadKey(); } } }
2.8 三元表达式 语法: 表达式1?表达式2:表达式3;
表达式1一般为一个关系表达式 如果1为True,结果为2的值;如果1为False,结果为3的值 2与3与整个三元表达式类型须一致
案例: 随机数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 using System;namespace 随机数{ class Program { static void Main (string [] args ) { while (true ) { Random r = new Random(); int rNumber = r.Next(1 , 11 ); Console.WriteLine(rNumber); Console.ReadKey(); } } } }
3 复杂数据类型 3.1 常量 不能被重新赋值
语法: const 变量类型 变量名 = 值;
3.2 枚举 语法: [public] enum 枚举名 { 值1, 值2, 值3, ... }
public: 访问修饰符,公开的,哪都可以访问 enum: 声明枚举的关键字 枚举名: Pascal命名规范
枚举就是一个变量类型,只是枚举声明、赋值、使用的方式与普通变量类型不同
枚举类型和string、int类型之间转换:
枚举类型与int类型是兼容的(枚举从0开始),可以使用强制类型转换相互转换 int类型转枚举:超出枚举范围直接输出int值 Enum.Parse(typeof(要转换的枚举类型即枚举名),“要转换的字符串”)字符串转换为枚举类型如果转换的字符串是数字且枚举中没有,不会抛异常 如果转换的是文本且枚举中没有,会抛异常 所有类型都可以转换为string类型 调用ToString() 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 using System;namespace 枚举{ public enum Gender { 男, 女 } class Program { static void Main (string [] args ) { Gender gender = Gender.男; Console.ReadKey(); } } }
3.3 结构 作用: 一次性声明多个不同类型的变量
语法: [public] struct 结构名 { 成员;//字段 }
字段可以存储多个值,规范上每个字段前加一个下划线_
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 using System;namespace 结构{ public struct Person { public string _name; public int _age; public Gender _gender; } public enum Gender { 男, 女 } class Program { static void Main (string [] args ) { Person zsPerson; zsPerson._name = "张三" ; zsPerson._age = 11 ; zsPerson._gender = Gender.男; Console.WriteLine(zsPerson._name); Console.WriteLine(zsPerson._age); Console.WriteLine(zsPerson._gender); } } }
3.4 数组 一次性存储多个相同类型的变量
语法: 数组类型[] 数组名=new 数组类型[数组长度];
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 using System;namespace 数组{ class Program { static void Main (string [] args ) { int [] nums = new int [10 ]; int [] numsTwo = { 1 , 2 ,7 , 4 , 5 }; Array.Sort(numsTwo); Array.Reverse(numsTwo); for (int i=0 ;i<nums.Length;i++) { nums[i] = i; } for (int i = 0 ; i < nums.Length; i++) { Console.WriteLine(nums[i]); } Console.ReadKey(); } } }
冒泡排序 将数组中的元素从大到小或者从小到大进行排序
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 using System;namespace 冒泡排序{ class Program { static void Main (string [] args ) { int [] number = { 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 }; for (int i = 0 ; i < number.Length-1 ; i++) { for (int j=0 ;j<number.Length-i-1 ;j++) { if (number[j]>number[j+1 ]) { int temp = number[j + 1 ]; number[j + 1 ] = number[j]; number[j] = temp; } } } for (int i = 0 ; i < number.Length; i++) { Console.WriteLine(number[i]); } Console.ReadKey(); } } }
3.5 方法(函数) 函数就是将一堆代码进行重用的一种机制
语法:[public] static 返回值类型 方法名 ([参数列表]) { 方法体; }
static: 静态的 方法名: Pascal命名规则
方法写好后需在Main()函数中调用 调用语法:类名.方法名([参数]);
如果你写的方法跟Main()函数同在一个类(Program)中,类名可以省略
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System;namespace 方法{ class Program { static void Main (string [] args ) { int max=Program.GetMax(1 , 3 ); Console.WriteLine(max); Console.ReadKey(); } public static int GetMax (int n1,int n2 ) { return n1 > n2 ? n1 : n1; } } }
return作用: 1.在方法中返回要返回的函数值 2.立即结束本方法
调用者:Main()函数中调用其他方法;被调用者:其他方法
如果被调用者要使用调用者的值:
传递参数 使用静态字段来模拟全局变量 public static int _number = 10;
(函数外,Program类中) 如果调用者要得到被调用者的值:
不管是实参还是形参都是在内存中开辟了空间的
方法的功能一定是单一的,方法中最忌讳的就是出现提示用户输入的字眼
3.5.1 out参数 返回多个类型相同的值的时候,可以考虑返回一个数组 返回对个不同类型的值的时候,可以考虑使用out参数
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 using System;namespace out 参数{ class Program { static void Main (string [] args ) { int [] numbers = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }; int [] res = GetMaxMinSumAvg(numbers); Console.WriteLine("最大值是{0},最小值是{1},总和是{2},平均值是{3}" ,res[0 ],res[1 ],res[2 ],res[3 ]); int max; int min; int sum; int avg; bool b; string s; double d; Test(numbers, out max, out min, out sum, out avg,out b,out s,out d); Console.WriteLine(max); Console.WriteLine(min); Console.WriteLine(sum); Console.WriteLine(avg); Console.WriteLine(b); Console.WriteLine(s); Console.WriteLine(d); Console.ReadKey(); } public static int [] GetMaxMinSumAvg (int [] nums ) { int [] res = new int [4 ]; res[0 ] = nums[0 ]; res[1 ] = nums[0 ]; res[2 ] = 0 ; for (int i=0 ;i<nums.Length;i++) { if (nums[i]>res[0 ]) { res[0 ] = nums[i]; } if (nums[i]<res[1 ]) { res[1 ] = nums[i]; } res[2 ] += nums[i]; } res[3 ] = res[2 ] / nums.Length; return res; } public static void Test (int [] nums, out int max, out int min, out int sum, out int avg, out bool b, out string s, out double d ) { max = nums[0 ]; min = nums[0 ]; sum = 0 ; for (int i = 0 ; i < nums.Length; i++) { if (nums[i] > max) { max = nums[i]; } if (nums[i] < min) { min = nums[i]; } sum += nums[i]; } avg = sum / nums.Length; b = true ; s = "123" ; d = 3.14 ; } } }
3.5.2 ref参数 能够将一个变量带入一个方法中进行改变,改变完成后,再将改变后的值带出方法
要求:在方法外必须赋初值
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System;namespace ref 参数{ class Program { static void Main (string [] args ) { double salary = 5000 ; JiangJin(ref salary); Console.WriteLine(salary); Console.ReadKey(); } public static void JiangJin (ref double s ) { s += 500 ; } public static void FaKuan (double s ) { s -= 500 ; } } }
3.5.3 params可变参数 将实参列表中跟可变参数数组类型一致的元素都当做数组的元素去处理
params可变参数只能做最后一个参数且只能有一个
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System;namespace params 参数{ class Program { static void Main (string [] args ) { int [] score = { 98 ,78 ,90 }; Test("张三" , 360 ,98 , 78 , 90 ); Console.ReadKey(); } public static void Test (string name, int id,params int [] score ) { int sum = 0 ; for (int i=0 ;i<score.Length;i++) { sum += score[i]; } Console.WriteLine("{0}这次考试的总成绩是{1},学号为{2}" , name, sum,id); } } }
3.5.4 方法的重载 方法的重载指的是方法的名称相同、参数不同
参数个数相同,类型就不能相同 参数类型相同,个数就不能相同 3.5.5 方法的递归 递归:方法自己调用自己
案例: 飞行棋 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 using System;namespace 飞行棋项目{ class Program { public static int [] Maps = new int [100 ]; public static int [] PlayerPos = new int [2 ]; public static string [] PlayerNames = new string [2 ]; public static bool [] Flags = new bool [2 ]; static void Main (string [] args ) { GameShow(); #region 输入姓名 Console.WriteLine("请输入玩家A的姓名:" ); PlayerNames[0 ] = Console.ReadLine(); while (PlayerNames[0 ]=="" ) { Console.WriteLine("玩家A的姓名不能为空" ); PlayerNames[0 ] = Console.ReadLine(); } Console.WriteLine("请输入玩家B的姓名:" ); PlayerNames[1 ] = Console.ReadLine(); while (PlayerNames[1 ] == "" ||PlayerNames[1 ]==PlayerNames[0 ]) { if (PlayerNames[1 ]=="" ) { Console.WriteLine("玩家A的姓名不能为空" ); PlayerNames[1 ] = Console.ReadLine(); }else { Console.WriteLine("玩家B的姓名不能跟A的相同,请重新输入" ); PlayerNames[1 ] = Console.ReadLine(); } } #endregion Console.Clear(); GameShow(); Console.WriteLine("{0}的士兵用A表示" ,PlayerNames[0 ]); Console.WriteLine("{0}的士兵用B表示" ,PlayerNames[1 ]); InitailMap(); DrawMap(); while (PlayerPos[0 ]<99 &&PlayerPos[1 ]<99 ) { if (Flags[0 ]==false ) { PlayGame(0 ); } else { Flags[0 ] = false ; } if (PlayerPos[0 ]>=99 ) { Console.WriteLine("玩家{0}胜利" ,PlayerNames[0 ]); break ; } if (Flags[1 ] == false ) { PlayGame(1 ); } else { Flags[1 ] = false ; } if (PlayerPos[1 ] >= 99 ) { Console.WriteLine("玩家{0}胜利" , PlayerNames[1 ]); break ; } } Console.ReadKey(); } public static void GameShow () { Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine("************************" ); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("************************" ); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("*******飞行棋项目*******" ); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("************************" ); Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine("************************" ); } public static void InitailMap () { int [] luckyturn = { 6 , 23 , 40 , 55 , 69 , 83 }; for (int i=0 ;i<luckyturn.Length;i++) { Maps[luckyturn[i]] = 1 ; } int [] landMine = { 5 , 13 , 17 , 33 , 38 , 50 , 64 , 80 , 94 }; for (int i = 0 ; i < landMine.Length; i++) { Maps[landMine[i]] = 2 ; } int [] pause = { 9 , 27 , 60 , 93 }; for (int i = 0 ; i < pause.Length; i++) { Maps[pause[i]] = 3 ; } int [] timeTunnel = { 20 , 25 , 45 , 63 , 72 , 88 , 90 }; for (int i = 0 ; i < timeTunnel.Length; i++) { Maps[timeTunnel[i]] = 4 ; } } public static void DrawMap () { Console.WriteLine("图例:幸运圆盘:◎ 地雷:☆ 暂停:▲ 时空隧道:卐 " ); #region 第一横行 for (int i=0 ;i<30 ;i++) { Console.Write(DrawStringMap(i)); } #endregion Console.WriteLine(); #region 第一竖行 for (int i=30 ;i<35 ;i++) { for (int j=0 ;j<=28 ;j++) { Console.Write(" " ); } Console.Write(DrawStringMap(i)); Console.WriteLine(); } #endregion #region 第二横行 for (int i=64 ;i>=35 ;i--) { Console.Write(DrawStringMap(i)); } #endregion Console.WriteLine(); #region 第二竖行 for (int i=65 ;i<=69 ;i++) { Console.WriteLine(DrawStringMap(i)); } #endregion #region 第三横行 for (int i=70 ;i<=99 ;i++) { Console.Write(DrawStringMap(i)); } #endregion Console.WriteLine(); } public static string DrawStringMap (int i ) { string str="" ; #region 画图 if (PlayerPos[0 ] == PlayerPos[1 ] && PlayerPos[1 ] == i) { str="<>" ; } else if (PlayerPos[0 ] == i) { str="A" ; } else if (PlayerPos[1 ] == i) { str="B" ; } else { switch (Maps[i]) { case 0 : Console.ForegroundColor = ConsoleColor.Yellow; str = "□" ; break ; case 1 : Console.ForegroundColor = ConsoleColor.Red; str = "◎" ; break ; case 2 : Console.ForegroundColor = ConsoleColor.Cyan; str = "☆" ; break ; case 3 : Console.ForegroundColor = ConsoleColor.Green; str = "▲" ; break ; case 4 : Console.ForegroundColor = ConsoleColor.Blue; str="卐" ; break ; } } return str; #endregion } public static void PlayGame (int playerNumber ) { Random r = new Random(); int rNumber = r.Next(1 , 7 ); Console.WriteLine("{0}按任意键开始掷骰子" , PlayerNames[playerNumber]); Console.ReadKey(true ); Console.WriteLine("{0}掷出了{1}" , PlayerNames[playerNumber],rNumber); PlayerPos[playerNumber] += rNumber; ChangePos(); Console.ReadKey(true ); Console.WriteLine("{0}按任意键继续行动" , PlayerNames[playerNumber]); Console.ReadKey(true ); Console.WriteLine("{0}行动完了" , PlayerNames[playerNumber]); Console.ReadKey(true ); if (PlayerPos[playerNumber] == PlayerPos[1 - playerNumber]) { Console.WriteLine("玩家{0}踩到玩家{1},玩家{2}退6格" , PlayerNames[playerNumber], PlayerNames[1 - playerNumber], PlayerNames[1 - playerNumber]); PlayerPos[1 - playerNumber] -= 6 ; ChangePos(); Console.ReadKey(true ); } else { switch (Maps[PlayerPos[playerNumber]]) { case 0 : Console.WriteLine("玩家{0}踩到了方块,安全" , PlayerNames[playerNumber]); Console.ReadKey(true ); break ; case 1 : Console.WriteLine("玩家{0}踩到了幸运圆盘,请选择:1--交换位置,2--轰炸对方" , PlayerNames[playerNumber]); string input = Console.ReadLine(); while (true ) { if (input == "1" ) { Console.WriteLine("玩家{0}与玩家{1}交换位置" , PlayerNames[playerNumber], PlayerNames[1 - playerNumber]); Console.ReadKey(true ); int temp = PlayerPos[playerNumber]; PlayerPos[playerNumber] = PlayerPos[1 - playerNumber]; PlayerPos[1 - playerNumber] = temp; Console.WriteLine("交换完成,按任意键继续!!!" ); Console.ReadKey(true ); break ; } else if (input == "2" ) { Console.WriteLine("玩家{0}轰炸玩家{1},玩家{2}退6格" , PlayerNames[playerNumber], PlayerNames[1 - playerNumber], PlayerNames[1 - playerNumber]); Console.ReadKey(true ); PlayerPos[1 - playerNumber] -= 6 ; ChangePos(); Console.WriteLine("玩家{0}退了6格" , PlayerNames[1 - playerNumber]); Console.ReadKey(true ); break ; } else { Console.WriteLine("只能输入1或者2 :1--交换位置,2--轰炸对方" ); input = Console.ReadLine(); } } break ; case 2 : Console.WriteLine("玩家{0}踩到了地雷,退6格" , PlayerNames[playerNumber]); Console.ReadKey(true ); PlayerPos[playerNumber] -= 6 ; ChangePos(); break ; case 3 : Console.WriteLine("玩家{0}踩到了暂停,暂停一回合" , PlayerNames[playerNumber]); Flags[playerNumber] = true ; Console.ReadKey(true ); break ; case 4 : Console.WriteLine("玩家{0}踩到了时空隧道,前进10格" , PlayerNames[playerNumber]); PlayerPos[playerNumber] += 10 ; ChangePos(); Console.ReadKey(true ); break ; } } ChangePos(); Console.Clear(); DrawMap(); } public static void ChangePos () { if (PlayerPos[0 ]<0 ) { PlayerPos[0 ] = 0 ; } if (PlayerPos[0 ] >99 ) { PlayerPos[0 ] = 99 ; } if (PlayerPos[1 ] < 0 ) { PlayerPos[1 ] = 0 ; } if (PlayerPos[1 ] > 99 ) { PlayerPos[1 ] = 99 ; } } public static void Test (string [] names ) { for (int i = 0 ; i < names.Length / 2 ; i++) { string temp = names[i]; names[i] = names[names.Length - 1 - i]; names[names.Length - 1 - i] = temp; } } } }
4 面向对象 面向对象意在写出一个通用的代码屏蔽差异
描述一个对象通常描述这个对象的属性和方法
类:将具有相同属性和方法的对象进一步封装,抽象出类的概念
对象是根据类创建出来的
4.1 类 语法:[public] class 类名 { 字段(Fiels); 属性(Property); 方法(Method); }
添加类:需要添加类的项目->右键->添加->类(.cs)
写好一个类之后,我们需要创建这个类的对象,我们称创建类的过程称为类的实例化,使用关键字new
类不占内存,对象占内存
属性的作用就是保护字段、对字段的赋值和取值进行限定。 属性的本质就是get(读)和set(写)俩个方法
访问修饰符:
public:公开的,在哪都能访问 private:私有的,只能在当前类的内部进行访问,出了这个类就访问不到 静态与非静态的区别: 1.在非静态类中,既可以有实例成员,也可以有静态成员 2.在调用实例成员时,需要使用对象名.实例成员
在调用静态成员时,需要使用类名.静态成员名
总结:
静态成员必须使用类名区调用,而实例成员使用对象名区调用 静态函数中,只能访问静态成员,不允许访问实例成员 实例函数中,既可以访问静态成员,也可以访问实例成员 静态类中只允许有静态成员,不允许出现实例成员 使用: 1.如果你需要将你的类当做一个工具类使用时可以考虑将类写成静态的 2.静态类在整个项目中资源共享 只有在程序全部结束后静态类才会释放资源
堆、栈 静态存储区域
释放资源:GC
构造函数: 创建对象时会执行构造函数 构造函数可以有重载 作用:帮助我们初始化对象 构造函数是一个特殊的方法: 1.没有返回值,连void也不用写 2.名称必须跟类名一样
类中有一个默认的无参数的构造函数,当你写了一个新的构造函数会替代原先的构造函数
new关键字帮我们干的3件事: 1.在内存中开辟一块空间 2.在开辟的空间中创建对象 3.调用对象的构造函数进行初始化对象
this关键字: 1.代表当前类的对象 2.在类中显示调用本类的构造函数 :this
析构函数: 当程序结束时,析构函数才执行 作用:帮助我们释放资源
Person.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 面向对象初级{ public class Person { ~Person() { Console.WriteLine("析构函数调用" ); } public Person (string name,int age,char gender ) { this ._name = name; this ._age = age; this ._gender = gender; Console.WriteLine("构造函数" ); } public Person (string name, int age ):this (name,age,'男' ) { } public Person (string name ) { this ._name = name; } private string _name; public string Name { get { return _name; } set { _name = value ; } } private int _age; public int Age { get { return _age; } set { if (value <0 ||value >100 ) { value = 0 ; } _age = value ; } } char _gender; public char Gender { get { if (_gender!='男' &&_gender!='女' ) { return _gender = '男' ; } return _gender; } set { _gender = value ; } } public void CHLSS () { Console.WriteLine("{0},{1}岁,{2},会吃喝拉撒睡" ,this .Name,this .Age,this .Gender); } } }
Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 using System;namespace 面向对象初级{ class Program { static void Main (string [] args ) { Person sunQuan = new Person("孙权" ,18 ,'男' ); sunQuan.CHLSS(); Console.ReadKey(); } } }
4.2 命名空间 导入类所在命名空间: 1.用鼠标点 2.alt+shift+F10 3.记住常见类的命名空间,手敲
一个项目中引用另一个项目的类 1.添加引用:引用->右键->引用 2.引用命名空间 using 命名空间;
4.3 值类型和引用类型 区别: 1.在内存上存储的地方不一样 2.在传递值类型和传递引用类型时,传递的方式不同(值传递和引用传递)
值传递:int、double、bool、char、decimal、struct、enum 引用传递:string、自定义类、数组
存储: 值类型的值是存储在内存的栈当中 引用类型的值是存储在内存的堆中
4.4 字符串 1.字符串的不可变性(当重新给一个字符串赋值后,原来值并没用销毁,而是重新开辟一块内存存储新值) 当程序结束后,GC扫描整个内存,如果发现有的空间没有被指向,立即将它销毁
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string s1 = "张三" ; string s2 = "张三" ; Console.ReadKey(); } } }
2.可以将字符串看成是char类型的只读数组,可以通过下标访问字符串中的一个元素
将字符串转换为char类型数组 字符串.ToCharArray()
将字符数组转换为字符串 new string(字符数组)
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string s = "abcdef" ; Console.WriteLine(s[0 ]); char [] chs = s.ToCharArray(); chs[0 ] = 'b' ; s = new string (chs); Console.WriteLine(s[0 ]); Console.WriteLine(s); Console.ReadKey(); } } }
StringBuilder:不开内存空间,比string快 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { StringBuilder sb = new StringBuilder(); string str = null ; Stopwatch sw = new Stopwatch(); sw.Start(); for (int i=0 ;i<100000 ;i++) { sb.Append(i); } sw.Stop(); Console.WriteLine(sb.ToString()); Console.WriteLine(sw.Elapsed); Console.ReadKey(); } } }
s.ToUpper() 转换为大写 s.ToLower() 转换为小写 s1.Equals(s1,StringComparison.OrdinalIgnoreCase) 比较 StringComparison.OrdinalIgnoreCase:忽略比较字符串大小写
**分割字符串:**s.Split(chs,StringSplitOptions.RemoveEmptyEntries) chs:需要移除的字符数组 StringSplitOptions.RemoveEmptyEntries:去除空项 返回字符串类型数组
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string s = "a b dfd _+ = ,,, fdf" ; char [] chs = { ' ' , '_' , '+' , '=' , ',' }; string [] str = s.Split(chs,StringSplitOptions.RemoveEmptyEntries); Console.ReadKey(); } } }
s1.Contains(s2) s1包含s2 s.Replace(要替换的内容,替换成为的内容) 替换
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string str = "国家关键人物老赵" ; if (str.Contains("老赵" )) { str = str.Replace("老赵" , "**" ); } Console.WriteLine(str); Console.ReadKey(); } } }
s.SubString(起始位置0开始,截取个数) 截取字符串
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string str = "今天天气好晴朗,处处好风光" ; str = str.Substring(1 ,2 ); Console.WriteLine(str); Console.ReadKey(); } } }
s.StartsWith(str) 以什么开始,返回bool类型 s.EndsWith(str) 以什么结尾,返回bool类型
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string str = "今天天气好晴朗,处处好风光" ; if (str.StartsWith("今天" )) { Console.WriteLine("是" ); } else { Console.WriteLine("不是" ); } Console.ReadKey(); } } }
str.IndexOf(字符串,开始查找位置包括当前位置); 判读该字符串第一次出现位置,从0开始 str.LastIndexOf(字符串,开始查找位置包括当前位置); 判断该字符串最后出现位置,从0开始
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string str = "今天天气好晴朗,处处好风光" ; int index = str.IndexOf('天' ,2 ); int index1 = str.LastIndexOf('天' ,2 ); Console.WriteLine(index); Console.WriteLine(index1); Console.ReadKey(); } } }
str.Trim(); 去空格 返回string类型 str.TrimStart(); 去前面空格 返回string类型 str.TrimEnd(); 去后面空格 返回string类型
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string str = " hahaha " ; str = str.TrimEnd(); Console.Write(str); Console.ReadKey(); } } }
string.IsNullOrEmpty(str) 判断字符串是否为NULL或Empty
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string str = null ; if (string .IsNullOrEmpty(str)) { Console.WriteLine("是的" ); } else { Console.WriteLine("不是" ); } Console.ReadKey(); } } }
string.Join(字符串, 可变数组); 将数组按照指定的字符串连接,返回一个字符串
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string [] names = { "张三" , "李四" , "王五" , "赵六" }; string strNew = string .Join("|" , names); Console.WriteLine(strNew); Console.ReadKey(); } } }
案例: 字符串使用 案例描述: 文本文件中存储了多个文章标题、作者, 标题和作者之间用若干空格(数量不定)隔开,每行一个, 标题有的长有的短,输出到控制台的时候最多标题长度10. 如果超过10,则截取长度8的子串并且最后添加“…”,加一个竖线后输出作者的名字。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 using System;using System.Diagnostics;using System.IO;using System.Text;namespace 字符串{ class Program { static void Main (string [] args ) { string path = @"文件路径" ; string [] contents = File.ReadAllLines(path, Encoding.Default); for (int i=0 ;i<contents.Length;i++) { string [] strNew = contents[i].Split(new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Console.WriteLine((strNew[0 ].Length > 10 ? strNew[0 ].Substring(0 , 8 )+"......r" : strNew[0 ]) + "|" + strNew[1 ]); } Console.ReadKey(); } } }
4.5 继承 子类 派生类 父类 基类 子类继承了父类,继承了父类的属性和方法,但是子类没有继承父类的私有字段
继承的特性: 1.单根性:一个子类只能有一个父类 2.传递性
子类并没有继承父类的构造函数,但是子类会默认调用父类无参数的构造函数创建父类对象,让子类可以使用父类中的成员。所以,如果在父类中重新写了一个有参数的构造函数后,那个无参数的就被干掉了,子类就调用不到了,所以子类会报错。 解决方法: 1.在父类中重新写一个无参数的构造函数 2.在子类中显示的调用父类的构造函数,使用关键字:base()
object是所有类的基类
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 using System;namespace 继承{ class Program { static void Main (string [] args ) { Reporter rep = new Reporter("狗仔" , 34 ,'男' ,"偷拍" ); rep.ReporterSayHello(); Programmer pro = new Programmer("程序猿" , 23 , '男' , 3 ); pro.ProgrammerSayHello(); Console.ReadKey(); } } public class Person { private string _name; public string Name { get { return _name; } set { _name = value ; } } private int _age; public int Age { get { return _age; } set { _age = value ; } } private char _gender; public char Gender { get { return _gender; } set { _gender = value ; } } public Person (string name, int age,char gender ) { this .Name = name; this .Age = age; this .Gender = gender; } public void SayHello () { Console.WriteLine("大家好,我是人类" ); } } public class Reporter : Person { public Reporter (string name,int age,char gender,string hobby ) :base (name,age,gender ) { this .Hobby = hobby; } private string _hobby; public string Hobby { get { return _hobby; } set { _hobby = value ; } } public void ReporterSayHello () { Console.WriteLine("我叫{0},我是一名记者,我的爱好是{1},我是{2}生,我今年{3}岁" , this .Name, this .Hobby, this .Gender, this .Age); } public new void SayHello () { Console.WriteLine("大家好,我是记者" ); } } public class Programmer : Person { public Programmer (string name, int age, char gender, int workYear ) : base (name, age, gender ) { this .WorkYear = workYear; } private int _workYear; public int WorkYear { get { return _workYear; } set { _workYear = value ; } } public void ProgrammerSayHello () { Console.WriteLine("我叫{0},我是一名程序员,我是{1}生,我今年{2}岁,我的工作年限是{3}年" , this .Name, this .Gender, this .Age,this .WorkYear); } public new void SayHello () { Console.WriteLine("大家好,我是程序猿" ); } } }
new关键字: 1.创建对象 2.隐藏从父类继承过来的同名成员 隐藏后果:子类调用不到父类的成员
4.6 里氏转换 1.子类可以赋值给父类 如果有一个地方需要父类作为参数,我们可以给一个子类代替 2.如果父类中装的是子类对象,那么可以将这个父类强转为子类对象
子类对象可以调用父类的成员,但是父类对象只能调用自己的成员
is: 表示类型转换,如果能转换成功,则返回true,不能转换成功返回false as: 表示类型转换,如果能够转换则返回对应的对象,否则返回一个NULL
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 using System;namespace 里氏转换{ class Program { static void Main (string [] args ) { Person p = new Student(); Student t = p as Student; t.StudentSayHello(); Console.ReadKey(); } } public class Person { public void PersonSayHello () { Console.WriteLine("我是父类" ); } } public class Student :Person { public void StudentSayHello () { Console.WriteLine("我是学生" ); } } public class Teacher : Person { public void TeacherSayHello () { Console.WriteLine("我是老师" ); } } }
protected 受保护的:可以在当前类的内部以及该类的子类中访问
4.7 ArrayList集合 集合好处(相对于数组): 1.长度可以任意改变 2.类型随意
我们将一个对象输出到控制台,默认情况下就是打印这个对象的命名空间
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 using System;using System.Collections;namespace ArrayList 集合{ class Program { static void Main (string [] args ) { ArrayList list = new ArrayList(); list.Add(1 ); list.Add(3.14 ); list.Add(true ); list.Add("张三" ); list.Add('男' ); list.Add(5000 m); list.Add(new int [] { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }); Person p = new Person(); list.Add(p); list.Add(list); list.Remove(true ); list.RemoveAt(0 ); for (int i=0 ;i<list.Count;i++) { if (list[i] is Person) { ((Person)list[i]).SayHello(); }else if (list[i] is int []) { for (int j=0 ;j<((int [])list[i]).Length;j++) { Console.WriteLine(((int [])list[i])[j]); } } else { Console.WriteLine(list[i]); } } list.Clear(); list.AddRange(new int [] { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }); list.AddRange(list); list.RemoveRange(0 , 8 ); list.Sort(); list.Reverse(); list.Insert(1 , 9 ); bool b = list.Contains(1 ); for (int i=0 ;i<list.Count;i++) { Console.WriteLine(list[i]); } Console.WriteLine(b); Console.WriteLine(list.Count); Console.WriteLine(list.Capacity); Console.ReadKey(); } } public class Person { public void SayHello () { Console.WriteLine("Hello" ); } } }
ArrayList集合长度:
count 表示这个集合中实际包含的元素个数 没元素:0 capcity 表示这个集合中可以包含的元素个数 没元素:0 当实际包含的元素个数(count)超过了可以包含的元素个数(capcity)时,集合就会向内存中申请多开一倍的空间来保证集合的长度一直够用 4.8 HashTable集合 (键值对集合) 类似于生活中的字典,键值对对象[键]=值
键值对集合中,键必须是唯一的,值可以是重复的
使用foreach循环输出,不能使用for循环 var:根据值能够推断出来类型
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Hashtable 集合{ class Program { static void Main (string [] args ) { Hashtable ht = new Hashtable(); ht.Add(1 ,"张三" ); ht.Add(2 , true ); ht.Add(3 , '男' ); ht.Add(false , "错误的" ); ht[5 ] = "new" ; ht[1 ] = "换掉张三" ; foreach (var item in ht.Keys) { Console.WriteLine("键是---{0},值是---{1}" ,item,ht[item]); } Console.ReadKey(); } } }
4.9 Path类 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 using System;using System.IO;namespace Path 类{ class Program { static void Main (string [] args ) { string str = @"文件路径" ; Console.WriteLine(Path.GetFileName(str)); Console.WriteLine(Path.GetFileNameWithoutExtension(str)); Console.WriteLine(Path.GetExtension(str)); Console.WriteLine(Path.GetDirectoryName(str)); Console.WriteLine(Path.GetFullPath(str)); Console.WriteLine(Path.Combine(@"c:\a\" ,"b.txt" )); Console.ReadKey(); } } }
4.10 File类 File.Exists():判断是否存在 File.Copy():复制文件 File.Move():剪切,俩个参数,第一个原地址,第二个新地址 File.Delete():删除
读取文件的三个方法:
1.byte[] buffer = File.ReadAllBytes(@"文件路径"); string str = System.Text.Encoding.Default.GetString(buffer);//将二进制转换为字符串
2.string[] str = File.ReadAllLines(@"文件路径",Encoding.Default);//读取所有行
3.string str = File.ReadAllText(@"文件路径",Encoding.Default);
写入文件:
1.byte[] buffer = System.Text.Encoding.Default.GetBytes(str);//将字符串转换为字节数组 File.WriteAllBytes(@"文件路径",buffer);
2.File.WriteAllLines(@"文件路径",str数组);
3.File.WriteAllText(@"文件路径",str);
File.AppendAllText(@“文件路径”,str);//追加文字
多媒体(只能以字节形式)的复制:byte[] buffer = File.ReadAllBytes(@"文件路径"); File.WriteAllBytes(@"存放路径",buffer);
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System;using System.IO;namespace File 类{ class Program { static void Main (string [] args ) { File.Copy(@"F:\new.txt" , @"F:\copy.txt" ); Console.WriteLine("复制成功" ); Console.ReadKey(); } } }
编码:
ASC 128 ASCII 256
GB2312 简体字(中国) Big5 繁体字
unicode 全,但解析慢 UTF-8 web
将字符串以怎样的形式保存为二进制
乱码: 产生原因:保存文件的编码和打开文件的编码格式不同
Directory操作 Directory.CreateDirectory():创建文件夹 Directory.Delete(@“文件夹路径”,true):删除文件夹 true表示即使该文件夹下不为空也删除 Directory.Exists():判断文件夹是否存在 Directory.Move():剪切 Directory.GetDirectories():得到该路径下所有文件夹路径的字符串数组 Directory.GetFiles():得到该路径下所有文件路径的字符串数组 第二个参数为指定文件后缀名 *.avi
FileStream 操作字节
File只能操作小文件;操作大文件(字符):StreamReader、StreamWriter
读:
1 2 3 4 5 6 7 8 9 10 FileStream fsRead = new FileStream(@"文件路径" ,FileMode.Open,FileAccess.Read); byte [] buffer = new byte [fsRead.Length];int r = fsRead.Read(buffer,0 ,buffer.Length);string str = System.Text.Encoding.Default.GetString(buffer);fsRead.Close(); fsRead.Dispose();
写: 追加:FileMode.Append
1 2 3 4 using (FileStream fsWrite = new FileStream(@"文件路径" ,FileMode.OpenOrCreate,FileAccess.Write)){ byte [] buffer = System.Text.Encoding.Default.GetBytes(str); fsWrite.Write(buffer,0 ,buffer.Length); }
多媒体文件的复制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public static void CopyFile (string source,string target ){ using (FileStream fsRead = new FileStream(source,FileMode.Open,FileAccess.Read)){ using (FileStream fsWrite = new FileStream(target,FileMode.OpenOrCreate,FileAccess.Write)){ byte [] buffer = new byte [1024 *1024 *7 ]; while (true ) { int r = fsRead.Read(buffer,0 ,buffer.Length); if (r==0 ) { return ; }else { fsWrite.Write(buffer,0 ,r); } } } } }
StreamReader读数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using (FileStream fsRead = new FileStream(@"文件路径" ,FileMode.Open,FileAccess.Read)){ using (StreamReader sr = new StreamReader(fsRead,Encoding.Default)){ while (!sr.EndOfStream) { Console.WriteLine(sr.ReadLine()); } } } Console.ReadKey(); using (StreamReader sr = new StreamReader(@"文件路径" ),Encoding.Default){ while (!sr.EndOfStream) { Console.WriteLine(sr.ReadLine()); } } Console.ReadKey();
StreamReader写数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 using (FileStream fsWrite = new FileStream(@"文件路径" ,FileMode.OpenOrCreate,FileAccess.Write)){ using (StreamWriter sw = new StreamWriter(fsWrite,Encoding.Default)){ sw.Write("xxx" ); } } Console.ReadKey(); using (StreamWriter sw = new StreamWriter(@"文件路径" ),true ){ sw.Write("xxx" ); } Console.ReadKey();
4.11 List泛型集合 方法跟ArrayList差不多
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 using System;using System.Collections.Generic;namespace List 泛型集合{ class Program { static void Main (string [] args ) { List<int > list = new List<int >(); list.Add(1 ); list.Add(2 ); list.Add(3 ); list.AddRange(new int [] { 1 , 2 , 3 , 4 , 5 , 6 }); list.AddRange(list); int [] nums = list.ToArray(); for (int i = 0 ; i < list.Count; i++) { Console.WriteLine(list[i]); } Console.ReadKey(); } } }
4.12 装箱和拆箱 装箱:就是将值类型转换为引用类型 拆箱:就是将引用类型转换为值类型
1 2 3 int n=10 ;object o=n;int nn=(int )o;
装箱会浪费时间,代码中应该避免装箱和拆箱
注意:Convert.ToInt(str)没有发生任意类型的装箱和拆箱
发生装箱和拆箱的条件:看是否有继承关系,有继承关系才有可能发生
4.13 Dictionary集合 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 using System;using System.Collections.Generic;namespace Dictionary 集合{ class Program { static void Main (string [] args ) { Dictionary<int , string > dic = new Dictionary<int , string >(); dic.Add(1 , "张三" ); dic.Add(2 , "李四" ); dic.Add(3 , "王五" ); dic[1 ] = "新来的" ; foreach (KeyValuePair<int ,string > kv in dic) { Console.WriteLine("{0}---{1}" , kv.Key, kv.Value); } Console.ReadKey(); } } }
4.14 多态 多态: 概念:让一个对象能够表现出多种状态(类型) 实现多态的3种手段: 1.虚方法
将父类方法标记为虚方法,在其返回类型之前加virtual
,这个函数子类要重写一遍,在重写方法返回类型前加override
2.抽象类
当父类中的方法不知道如何去实现时,可以考虑将父类写成抽象类abstract class
,将方法写成抽象方法abstract 返回类型
子类也需要重写(在重写方法返回类型前加override
),而且子类必须要实现父类中所有的抽象成员 实现多态:不能创建父类对象,可以创建子类对象Father f = new Son(); a.Eat();
抽象方法不能有方法体public abstract void func();
空实现:public abstract void func(){}
抽象类可以有非抽象成员,但是非抽象类中不能有抽象成员
如果子类也是抽象类,不用重写父类抽象成员
抽象类是由构造函数的,虽然不能被实例化
子类重写父类抽象函数时返回值和参数必须一样
如果父类中的方法有默认的实现,并且父类需要被实例化,这时可以考虑将父类定义成一个普通类,用虚方法来实现多态 如果父类中的方法没有默认实现,父类也不需要被实例化,则可以将父类定义为抽象类
抽象类也可以有虚方法,子类也不是必须要重写虚方法
案例:使用多态求矩形的面积和周长以及圆形的面积和周长 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 using System;namespace 抽象类{ class Program { static void Main (string [] args ) { Shape shape = new Circle(5 ); double area = shape.GetArea(); double perimeter = shape.GetPerimeter(); Console.WriteLine("面积:{0},周长:{1}" , area, perimeter); Console.ReadKey(); } } public abstract class Shape { public abstract double GetArea () ; public abstract double GetPerimeter () ; } public class Circle : Shape { private double _r; public double R { get { return _r; } set { _r = value ; } } public Circle (double r ) { this .R = r; } public override double GetArea () { return Math.PI * this .R * this .R; } public override double GetPerimeter () { return 2 * Math.PI * this .R; } } public class Square : Shape { private double _Height; public double Height { get { return _Height; } set { _Height = value ; } } private double _Width; public double Width { get { return _Width; } set { _Width = value ; } } public Square (double height,double width ) { this .Height = height; this .Width = width; } public override double GetArea () { return this .Height * this .Width; } public override double GetPerimeter () { return 2 * (this .Height + this .Width); } } }
3.接口
接口就是一个规范、能力
语法:[public] interface I...able { 成员; }
接口中的成员不允许添加访问修饰符 不允许写具有方法体的函数 自动属性 不能写字段和构造函数,只能有方法、属性、索引器、事件 一个类继承了一个接口就必须实现这个接口中所有成员 为了多态,接口不能被实例化,接口不能创建对象 接口中的成员不能有任何实现 接口与接口间可以继承,并且可以多继承 接口只能继承接口 类继承类A,继承接口B,写法上A在B前(先继承类)
显式实现接口就是为了解决方法重名问题
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 using System;namespace 显式实现接口{ class Program { static void Main (string [] args ) { IFlyable fly = new Bird(); fly.Fly(); Bird bird = new Bird(); bird.Fly(); Console.ReadKey(); } } public class Bird :IFlyable { public void Fly () { Console.WriteLine("鸟会飞" ); } void IFlyable.Fly() { Console.WriteLine("我是接口的Fly" ); } } public interface IFlyable { void Fly () ; } }
访问修饰符 public:公开的,公共的 private:私有的,只有在当前类的内部访问 protected:受保护的,只能在当前类的内部以及该类的子类中访问 internal:只能在当前项目中访问,在同一个项目中,与public权限一样 protected internal:protected+internal
1.能够修饰类的修饰符:public、internal(默认) 2.可访问性不一致 子类访问权限不能高于父类访问权限,因为子类会暴露父类成员
简单工厂设计模式 设计模式:设计这个项目的一种方式
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 using System;namespace 简单工厂设计模式{ class Program { static void Main (string [] args ) { Console.WriteLine("请输入你想要的笔记本品牌:" ); string brand = Console.ReadLine(); NoteBook nb = GetNoteBook(brand); nb.SayHello(); Console.ReadKey(); } public static NoteBook GetNoteBook (string brand ) { NoteBook nb = null ; switch (brand) { case "Lenovo" :nb = new Lenovo(); break ; case "IBM" :nb = new IBM(); break ; case "Acer" :nb = new Acer(); break ; case "Dell" :nb = new Dell(); break ; default : break ; } return nb; } } public abstract class NoteBook { public abstract void SayHello () ; } public class Lenovo : NoteBook { public override void SayHello () { Console.WriteLine("我是联想笔记本" ); } } public class Acer : NoteBook { public override void SayHello () { Console.WriteLine("我是鸿基笔记本" ); } } public class Dell : NoteBook { public override void SayHello () { Console.WriteLine("我是戴尔笔记本" ); } } public class IBM : NoteBook { public override void SayHello () { Console.WriteLine("我是IBM笔记本" ); } } }
值类型:int,double,char,decimal,bool,enum,struct 复制时,传递的是本身 引用类型:string,数组,自定义类,集合,object,接口 复制时,传递的是地址 注意:字符串的不可变型
加ref:值传递->引用传递
序列化和反序列化: 序列化:就是将对象转换为二进制 在类上加[Serializable]
反序列化:就是将二进制转换为对象
作用:传递数据
部分类:在类的class前加partial
,可以写相同类
密封类:在类的class前加sealed
,不能被继承,但是可以继承其他类
重写toString方法:
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 using System;namespace 重写toString 方法{ class Program { static void Main (string [] args ) { Person p = new Person(); Console.WriteLine(p.ToString()); Console.ReadKey(); } } public class Person { public override string ToString () { return "Hello World" ; } } }
案例: 超市收银系统 商品类、
GUID:产生一个不会重复的编号 Guid.NewGuid().toString()
代码:
ProductFather.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class ProductFather { public double Price { get ; set ; } public string Name { get ; set ; } public string ID { get ; set ; } public ProductFather (string id,double price,string name ) { this .ID = id; this .Name = name; this .Price = price; } } }
Acer.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class Acer :ProductFather { public Acer (string id,double price,string name ) : base (id, price, name ) { } } }
SamSung.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class SamSung :ProductFather { public SamSung (string id,double price,string name ) : base (id, price, name ) { } } }
JiangYou.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class JiangYou :ProductFather { public JiangYou (string id,double price,string name ) : base (id, price, name ) { } } }
Banana.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class Banana :ProductFather { public Banana (string id,double price,string name ) : base (id, price, name ) { } } }
CangKu.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class CangKu { List<List<ProductFather>> list = new List<List<ProductFather>>(); public void ShowPros () { foreach (var item in list) { Console.WriteLine("仓库有:" +item[0 ].Name+"\t\t" +"有" +item.Count+"个" +"\t\t每个" +item[0 ].Price+"元" ); } } public CangKu () { list.Add(new List<ProductFather>()); list.Add(new List<ProductFather>()); list.Add(new List<ProductFather>()); list.Add(new List<ProductFather>()); } public void JinPros (String strType,int count ) { for (int i = 0 ; i < count; i++) { switch (strType) { case "Acer" : list[0 ].Add(new Acer(Guid.NewGuid().ToString(),1000 ,"鸿基笔记本" )); break ; case "SamSung" : list[1 ].Add(new SamSung(Guid.NewGuid().ToString(), 800 , "三星手机" )); break ; case "JiangYou" : list[2 ].Add(new JiangYou(Guid.NewGuid().ToString(), 8 , "酱油" )); break ; case "Banana" : list[3 ].Add(new Banana(Guid.NewGuid().ToString(), 3 , "香蕉" )); break ; } } } public ProductFather[] QuPros (String strType, int count ) { ProductFather[] pros = new ProductFather[count]; for (int i = 0 ; i < pros.Length; i++) { switch (strType) { case "Acer" : pros[i]=list[0 ][0 ]; list[0 ].RemoveAt(0 ); break ; case "SamSung" : pros[i] = list[1 ][0 ]; list[1 ].RemoveAt(0 ); break ; case "JiangYou" : pros[i] = list[2 ][0 ]; list[2 ].RemoveAt(0 ); break ; case "Banana" : pros[i] = list[3 ][0 ]; list[3 ].RemoveAt(0 ); break ; default : break ; } } return pros; } } }
SupperMarket.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class SupperMarket { CangKu ck = new CangKu(); public SupperMarket () { ck.JinPros("Acer" , 1000 ); ck.JinPros("SamSung" , 1000 ); ck.JinPros("JiangYou" , 1000 ); ck.JinPros("Banana" , 1000 ); } public void AskBuying () { Console.WriteLine("欢迎光临,请问你要什么" ); Console.WriteLine("我们有Acer、SamSung、JiangYou、Banana" ); string strType = Console.ReadLine(); Console.WriteLine("你需要多少" ); int count = Convert.ToInt32(Console.ReadLine()); ProductFather[] pros = ck.QuPros(strType, count); double realMoney = GetMoney(pros); Console.WriteLine("你总共消费{0}元" , realMoney); Console.WriteLine("请选择打折方式:1--不打折,2--打9折,3--打85折,4--满300减50,5--满500减100" ); string input = Console.ReadLine(); CalFather cal = GetCal(input); double totalMoney=cal.GetTotalMoney(realMoney); Console.WriteLine("打折后价钱:{0}" , totalMoney); Console.WriteLine("以下是你的小票:" ); foreach (var item in pros) { Console.WriteLine("货物名称:{0}\t货物单价:{1}\t货物编号:{2}" , item.Name, item.Price, item.ID); } } public CalFather GetCal (string input ) { CalFather cal = null ; switch (input) { case "1" : cal=new CalNormal(); break ; case "2" : cal = new CalRate(0.9 ); break ; case "3" : cal = new CalRate(0.85 ); break ; case "4" : cal = new CalMN(300 ,50 ); break ; case "5" : cal = new CalMN(500 ,100 ); break ; default : break ; } return cal; } public double GetMoney (ProductFather[] pros ) { double realMoney = 0 ; for (int i = 0 ; i < pros.Length; i++) { realMoney += pros[i].Price; } return realMoney; } public void ShowPros () { ck.ShowPros(); } } }
CalFather.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ abstract class CalFather { public abstract double GetTotalMoney (double realMoney ) ; } }
CalNormal.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class CalNormal : CalFather { public override double GetTotalMoney (double realMoney ) { return realMoney; } } }
CalRate.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class CalRate : CalFather { public double Rate { get ; set ; } public CalRate (double rate ) { this .Rate = rate; } public override double GetTotalMoney (double realMoney ) { return realMoney * this .Rate; } } }
CalMN.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 超市收银系统{ class CalMN : CalFather { public double M { get ; set ; } public double N { set ; get ; } public CalMN (double m,double n ) { this .M = m; this .N = n; } public override double GetTotalMoney (double realMoney ) { if (realMoney>=this .M) { return realMoney - (int )(realMoney / this .M) * this .N; } else { return realMoney; } } } }
Main.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 using System;namespace 超市收银系统{ class Program { static void Main (string [] args ) { SupperMarket sm = new SupperMarket(); sm.ShowPros(); sm.AskBuying(); Console.ReadKey(); } } }
MD5加密 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 using System;using System.Security.Cryptography;using System.Text;namespace MD5 加密{ class Program { static void Main (string [] args ) { string s = GetMD5("123" ); Console.WriteLine(s); Console.ReadKey(); } public static string GetMD5 (string str ) { MD5 md5 = MD5.Create(); byte [] buffer = Encoding.Default.GetBytes(str); byte [] MD5Buffer = md5.ComputeHash(buffer); string strs = "" ; for (int i = 0 ; i < MD5Buffer.Length; i++) { strs += MD5Buffer[i].ToString("x2" ); } return strs; } } }
winform应用程序是一种智能客户端技术,我们可以使用winform应用程序帮助我们获得信息或者传输信息等
创建时选择Windows窗体应用(.NET Framework)
后台切前台:右键->查看设计器
属性:1.Name :在后台要获得前台的空间对象时需要使用Name属性 2.visible:指示一个控件是否可见 3.Enabled:指示一个控件是否可用
事件: 注册事件:双击控件注册的都是控件默认选中的那个事件 触发事件:
在Main函数中创建的窗体对象我们称之为这个窗体应用程序的主窗体
关闭所有窗体:
新建一个静态类
1 2 3 4 public static class Test { public static Form1 _fr1Test; }
主窗体load加载时发生:
需要调用关闭事件的地方:
Button常用事件:Click、MouseEnter
TextBox控件 属性: 1.WordWrap:指示文本框是否换行 2.PasswordChar:让文本框显示一个单一的字符 3.ScollBars:是否显示滚动条 事件:TextChanged:当文本框中内容改变时执行这个事件
Timer 在指定的一段时间间隔内 事件:Tick:每隔一段时间执行一次事件
播放音乐:
1 2 3 SoundPlayer sp = new SoundPlayer(); sp.SoundLocation = @"音乐文件路径(只支持.wav)" ; sp.play();
CheckBox 复选框 checked:指示这个空间是否选中
默认情况下,在一个窗体中,所有单选按钮只允许选中一个,但可以使用GroupBox容器:用于分组
MDI窗体设计 1.首先确定一个父窗体 isMdiContainer -> true 2.创建子窗体,并且设置他们的父窗体
代码
PictureBox .Image = Image.FromFile(图片全路径);
Directory 操作文件夹 CreateDirectory 创建文件夹 Delete 删除文件夹 Move 剪切文件夹 Exist 判断是否存在 GetFiles 获得指定目录下所有文件的全路径 GetDirectory 获得指定目录下所有文件夹的全路径
WebBrowser 浏览器控件 Url:网站网址
Uri uri = new Uri(“http://”+str);
ComboBox 下拉框控件 DropDownStyle:控制下拉框的外观样式
名字:cbo+…
.Items.Add()//添加 .Items.Clear()//清空 .SelectedItem.ToString()//获取当前选择的文本
案例: 日期选择器 代码
ListBox控件 .Items.Add()//添加
案例: 石头剪刀布 代码
对话框 打开对话框
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "" ; ofd.Multiselect = true ; ofd.InitialDirectory = @"全路径" ; ofd.Filter = "文本文件|*.txt|媒体文件|*.wmv|图片文件|*.jpg|所有文件|*.*" ; ofd.ShowDialog(); string path = ofd.FileName;if (path=="" ){ return ; } using (FileStream fsRead = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Read)){ byte [] buffer = new byte [1024 *1024 *5 ]; int r = fsRead.Read(buffer,0 ,buffer.Length); textBox.Text = Encoding.Default.GetString(buffer,0 ,r); }
保存对话框
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "" ; sfd.InitialDirectory = @"全路径" ; sfd.Filter = "文本文件|*.txt|媒体文件|*.wmv|图片文件|*.jpg|所有文件|*.*" ; sfd.ShowDialog(); string path = sfd.FileName;if (path=="" ){ return ; } using (FileStream fsWrite = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Write)){ byte [] buffer = Encoding.Default.GetBytes(textBox.Text); fsWrite.Write(buffer,0 ,buffer.Length); } MessageBox.Show("保存成功" );
字体和颜色对话框
1 2 3 4 5 6 7 FontDialog fd = new FontDialog(); fd.ShowDialog(); textBox.Font = fd.Font; ColorDialog cd = new ColorDialog(); cd.ShowDialog(); textBox.ForeColor = cd.Color;
panel.Visibel = false;//隐藏
进程类 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 using System;using System.Diagnostics;namespace 进程类{ class Program { static void Main (string [] args ) { ProcessStartInfo psi = new ProcessStartInfo(@"E:\test.txt" ); Process p = new Process(); p.StartInfo = psi; p.Start(); Console.ReadKey(); } } }
多线程 线程分类:
前台线程:只有所有前台线程都关闭才能完成程序关闭 后台线程:只要所有前台线程结束,后台线程自动关闭 单线程问题:
1 2 3 4 5 6 7 8 Thread th; th = new Thread(Test); th.IsBackground = true ; th.Start();
.NET下不允许跨线程访问
1 2 Control.CheckForIllegalCrossThreadCalls = false ;
关闭窗体时判断新线程是否为null,避免主线程关闭,新线程未关闭
Closing
1 2 3 4 5 if (th != null ){ th.Abort(); }
Thread.Sleep(3000);//休眠3秒
Socket网络编程 如果线程执行的方法需要参数,那么要求这个参数必须是object类型
1 2 3 4 5 6 7 8 9 10 11 12 13 Thread th = new Thread(Test); th.IsBackground = true ; th.Start("123" ); private void Test (object s ){ string ss = (string )s; for (int i = 0 ;i < 10000 ;i++) { Console.WriteLine(i); } }
TCP:3次握手 安全、稳定但效率低 UDP:快速、效率高,但是不稳定 容易发生数据丢失
服务器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 try { Socket socketWatch = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); IPAddress ip = IPAddress.Any; IPEndPoint point = new IPEndPoint(ip,Convert.ToInt32(txtPort.Text)); socketWatch.Bind(point); ShowMsg("监听成功" ); socketWatch.Listen(10 ); Thread th = new Thread(Listen); th.IsBackground = true ; th.Start(socketWatch); }catch {} Socket socketSend; void Listen (object o ){ Socket socketWatch = o as Socket; while (true ) { try { socketSend = socketWatch.Accept(); dicSocket.Add(socketSend.RemoteEndPoint.ToString(),socketSend); cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString()); ShowMsg(socketSend.RemoteEndPoint.ToString()+":" +"连接成功" ); Thread th = new Thread(Recive); th.IsBackground = true ; th.Start(socketSend); } catch {} } } Dictionary<string ,Socket> dicSocket = new Dictionary<string ,Socket>(); void Recive (object o ){ Socket socketSend = o as Socket; while (true ) { try { byte [] buffer = new byte [1024 *1024 *2 ]; int r = socketSend.Receive(buffer); if (r==0 ) { break ; } string str = Encoding.UTF8.GetString(buffer,0 ,r); ShowMsg(socketSend.RemoteEndPoint+":" +str); }catch {} } } void ShowMsg (string str ){ txtLog.AppendText(str + "\r\n" ); } string str = txtMsg.Text;byte [] buffer = System.Text.Encoding.UTF8.GetBytes(str);List<byte > list = new List<byte >(); list.Add(0 ); list.AddRange(buffer); byte [] newBuffer = list.ToArray();string ip = cboUsers.SelectedItem.ToString();dicSocket[ip].Send(newBuffer); OpenFileDialog ofd =new OpenFileDialog(); ofd.InitialDirectory = @"初始目录全路径" ; ofd.Title = "请选择要发送的文件" ; ofd.Filter = "所有文件|*.*" ; ofd.ShowDialog(); txtPath.Text = ofd.FileName; string path = txtPath.Text;using (FileStream fsRead = new FileStream(path,FileMode.Open,FileAccess.Read)){ byte [] buffer = new byte [1024 *1024 *5 ]; int r = fsRead.Read(buffer,0 ,buffer.Length); List<byte >list = new List<byte >(); list.Add(1 ); list.AddRange(buffer); byte [] newBuffer = list.ToArray(); dicSocket[cboUsers.SelectedItem.ToString()].Send(newBuffer,0 ,r+1 ,SocketFlags.None); } byte [] buffer = new byte [1 ];buffer[0 ] = 2 ; dicSocket[cboUsers.SelectedItem.ToString()].Send(buffer); Control.CheckForIllegalCrossThreadCalls = false ;
打开Telnet Client: 控制面板->查看方式(类别)->程序->程序和功能->启用或关闭Windows功能(在左边)->Telnet Client(勾上),点击确认
客户端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 Socket socketSend; try { socketSend = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); IPAddress ip = IPAddress.Parse(txtServer.Text); IPEndPoint point = new IPEndPoint(ip,Convert.ToInt32(txtPort.Text)); socketSend.Connect(point); ShowMsg("连接成功" ); Thread th = new Thread(Recive); th.IsBackground = true ; th.Start(); }catch {} void Recive (){ try { while (true ) { byte [] buffer = new byte [1024 *1024 *3 ]; int r = socketSend.Receive(buffer); if (r==0 ) { break ; } if (buffer[0 ]==0 ) { string s = Encoding.UTF8.GetString(buffer,1 ,r-1 ); ShowMsg(socketSend.RemoteEndPoint+":" +s); }else if (buffer[0 ]==1 ) { SaveFileDialog sfd = new SaveFileDialog(); sfd.InitialDirectory = @"保存默认地址" ; sfd.Title = "请选择要保存的文件" ; sfd.Filter = "所有文件|*.*" ; sfd.ShowDialog(this ); string path = sfd.FileName; using (FileStream fsWrite = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Write)) { fsWrite.Write(buffer,1 ,r-1 ); } MessageBox.Show("保存成功" ); }else if (buffer[0 ]==2 ) { ZD(); } } }catch {} } void ZD (){ for (int i = 0 ;i < 500 ;i++) { this .Location = new Point(200 ,200 ); this .Location = new Point(280 ,280 ); } } string str = txtMsg.Text.Trim();byte [] buffer = System.Text.Encoding.UTF8.GetBytes(str);socketSend.Send(); void ShowMsg (string str ){ txtLog.AppendText(str + "\r\n" ); } Control.CheckForIllegalCrossThreadCalls = false ;
开启多个项目:右键项目->调试->启动新实例
设计"协议":
GDI绘图 保留2位小数: avg = Convert.ToDouble(avg.ToString("0.00"));
窗体事件:Print 窗体重新绘制时都会画一遍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Graphics g = this .CreateGraphics(); Pen pen = new Pen(Brushes.Red); Size sizePie = new System.Drawing.Size(80 , 80 ); Rectangle recPie = new Rectangle(new Point(150 , 150 ), sizePie); g.DrawPie(pen, recPie, 60 , 60 ); Size size = new System.Drawing.Size(80 , 80 ); Rectangle rec = new Rectangle(new Point(50 ,50 ),size); g.DrawRectangle(pen, rec); Point p1 = new Point(30 , 50 ); Point p2 = new Point(25 , 250 ); g.DrawLine(pen, p1, p2);
案例: 验证码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 private void pictureBox1_Click (object sender, EventArgs e ){ Random r = new Random(); string str = null ;for (int i = 0 ; i < 5 ; i++){ int rNumber = r.Next(0 , 10 ); str += rNumber; } Bitmap bmp = new Bitmap(110 ,30 ); Graphics g = Graphics.FromImage(bmp); for (int i = 0 ; i < 5 ; i++){ Point p = new Point(i*20 ,0 ); string [] fonts = { "微软雅黑" , "宋体" , "隶书" , "黑体" , "仿宋" }; Color[] colors = { Color.Yellow, Color.Blue, Color.Green, Color.Black, Color.Red }; g.DrawString(str[i].ToString(),new Font(fonts[r.Next(0 ,5 )],20 ,FontStyle.Bold),new SolidBrush(colors[r.Next(0 ,5 )]),p); } for (int i = 0 ; i < 20 ; i++){ Point p1 = new Point(r.Next(0 ,bmp.Width),r.Next(0 ,bmp.Height)); Point p2 = new Point(r.Next(0 ,bmp.Width),r.Next(0 ,bmp.Height)); g.DrawLine(new Pen(Brushes.Green),p1,p2); } for (int i = 0 ; i < 500 ; i++){ Point p = new Point(r.Next(0 , bmp.Width), r.Next(0 , bmp.Height)); bmp.SetPixel(p.X,p.Y,Color.Black); } pictureBox1.Image = bmp;
代码
案例: 简单播放器 添加Windows Media Player
: 工具箱里找到组件右键->选择项->COM组件->找到Windows Media Player勾上并确认
windows media player控件的常用属性和方法
以下 music player 均为windows media player控件的名字。 1.属性 1)musicPlayer.settings.autoStart:打开播放器时是否自动播放 。true:自动播放,false:不自动播放,默认自动播放。 2)musicPlayer.URL:要播放歌曲的路径。 3)musicPlayer.settings.mute:是否静音。true:静音,false:不静音。 4)musicPlayer.settings.volume:音量值大小,范围是1 ~ 100。 5)musicPlayer.Ctlcontrols.currentPositionString:当前播放时间。返回值是字符串类型,例如:02:23。 6)musicPlayer.Ctlcontrols.currentPosition:也是返回当前播放的时间。返回值是 double 类型,例如:133.8。 7)musicPlayer.currentMedia.name :返回当前播放歌曲的名字。 8)musicPlayer.playState:播放器当前的状态。
有一个枚举 WMPLib.WMPPlayState 说明了它的取值: 0——wmppsUndefined:未知状态 1——wmppsStopped:播放停止 2——wmppsPaused:播放暂停 3——wmppsPlaying:正在播放 4——wmppsScanForward:向前搜索 5——wmppsScanReverse:向后搜索 6——wmppsBuffering :正在缓冲 7——wmppsWaiting:正在等待流开始 8——wmppsMediaEnded:播放流已结束 9——wmppsTransitioning :准备新的媒体文件 10——wmppsReady:播放准备就绪 11——wmppsReconnecting:尝试重新连接流媒体数据 12——wmppsLast:上一次状态,状态没有改变 2.方法 1)musicPlayer.Ctlcontrols.play():播放 2)musicPlayer.Ctlcontrols.pause():暂停 3)musicPlayer.Ctlcontrols.stop():停止
属性: url:音乐地址
1.在程序加载时取消播放器自动播放功能 2.播放或者暂停按钮 3.上一曲、下一曲 4.多选删除
给ListBox添加一个右键菜单 5.静音和放音 6.选择列表中的音乐文件,单击按钮直接播放 7.自动播放下一曲 代码
HTML 需要安装组件ASP.net 和 Web开发
中的其他项目模板(早期版本)
位置:展开最右边的ASP.NET和Web开发下拉菜单 新建网站项目: 选择ASP.NET 空网站
这个选项即可 添加html页:右键项目->添加->添加新项->HTML页
HTML:超文本标记语言
标签:
p: 段落标签  : 空格 h#: 标题标签 <!-- 要注释的内容 -->
: 注释符<img/>
: 图片标签src: 要显示图片的路径 height: 图片高度 width: 图片宽度 alt: 图片显示失败所显示的文本 title: 光标移动到图片上所显示的文本 <hr/>
: 分割线<font></font>
: 字体标签size=1 ~ 7 最大:7 color: 颜色 face: 字体系列 a标签:href: 要连接的地址 target: 打开新网页的方式(_blank
:打开一个新的页面;_self
:当前页面跳转) 作用: 1.实现页面内的跳转 2.实现页面间的跳转 3.发送邮件 div+span frame: 框架标签 更多请查看HTML
CSS CSS:控制网页内容的效果
更多请查看CSS
委托、XML、播放器项目 单例模式 1.将构造函数私有化 2.提供一个静态方法,返回一个对象 3.创建一个单例
XML:可扩展标记语言 存储数据 注意:XML严格区分大小写且也是成对出现 XML文档有且只有一个根节点 节点 元素
通过代码创建XML文档 1.引用命名空间
using System.Xml;
2.创建XML文档对象XmlDocument doc = new XmlDocument();
追加文档1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 XmlElement root; if (File.Exists("xxx.xml" )){ doc.Load("xxx.xml" ); root = doc.DocumentElement; } else { XmlDeclaration dec = doc.CreateXmlDeclaration("1.0" ,"utf-8" ,null ); doc.AppendChild(dec); root = doc.CreateElement("xxx" ); doc.AppendChild(root); }
读取XML文档
1 2 3 4 5 6 7 8 9 doc.Load("xxx.xml" ); XmlElement root = doc.DocumentElement; XmlNodeList xnl = root.ChildNodes; foreach (XmlNode item in xnl){ Console.WriteLine(item.InnerText); }
读取带属性XML文档
1 2 3 4 5 6 doc.Load("xxx.xml" ); XmlNodeList xnl = doc.SelectNodes("/xxx/xxx" ); foreach (XmlNode node in xnl){ Console.WriteLine(node.Attributes["属性名" ].Value); }
删除节点
1 2 3 4 doc.Load("xxx.xml" ); XmlNode xn = doc.SelectSingleNode("/xxx/xxx" ); xn.RemoveAll(); doc.Save("xxx.xml" );
3.创建第一行描述信息,并添加到文档中
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0","utf-8",null);
doc.AppendChild(dec);
4.创建根节点XmlElement root = doc.CreateElement("xxx");
doc.AppendChild(root);
5.创建子节点XmlElement child = doc.CreateElement("xxxxx");
6.给根节点添加子节点child.InnerText = "";
添加文本child.InnerXml = "";
添加标签child.setAttribute("属性名","属性值");
添加属性root.AppendChild(child);
doc.Save("xxx.xml");
保存的文件放在bin目录下
委托 1.为什么使用委托
将一个方法作为参数传递给另一个方法
2.委托概念
声明一个委托类型(命名空间下)public delegate void func(参数类型,参数名);
委托所指向的函数必须跟委托具有相同的签名(参数和返回值)
3.匿名函数
没有名字的函数 函数只调用一次时建议使用匿名函数 匿名函数必须跟委托具有相同的签名(参数和返回值)
4.练习:使用委托求数组最大值 5.练习:使用委托求任意数组最大值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 using System;namespace 委托求数组最大值{ class Program { public delegate int DelCompare (object o1,object o2 ) ; static void Main (string [] args ) { object [] o1 = { 1 , 2 , 3 , 4 , 5 }; object result1 = GetMax(o1, Compare1); object [] o2 = { "vhgfh" ,"yuewueg" ,"fdg" }; object result2 = GetMax(o2, (object o1,object o2) =>{ string s1 = (string )o1; string s2 = (string )o2; return s1.Length - s2.Length; }); Console.WriteLine(result2); Console.ReadKey(); } public static object GetMax (object []nums,DelCompare del ) { object max = nums[0 ]; for (int i = 0 ; i < nums.Length; i++) { if (del(max,nums[i])<0 ) { max = nums[i]; } } return max; } public static int Compare1 (object o1,object o2 ) { int n1 = (int )o1; int n2 = (int )o2; return n1 - n2; } public static int Compare2 (object o1, object o2 ) { string s1 = (string )o1; string s2 = (string )o2; return s1.Length - s2.Length; } } }
6.泛型委托
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 using System;namespace 泛型委托求数组最大值{ class Program { public delegate int DelCompare <T >(T o1,T o2 ) ; static void Main (string [] args ) { int [] nums= { 1 , 2 , 3 , 4 , 5 }; int result1 = GetMax<int >(nums, Compare1); string [] str = { "vhgfh" ,"yuewueg" ,"fdg" }; string result2 = GetMax<string >(str, (string s1, string s2) => { return s1.Length - s2.Length; }); Console.WriteLine(result2); Console.ReadKey(); } public static T GetMax <T >(T []nums,DelCompare<T> del ) { T max = nums[0 ]; for (int i = 0 ; i < nums.Length; i++) { if (del(max,nums[i])<0 ) { max = nums[i]; } } return max; } public static int Compare1 (int n1,int n2 ) { return n1 - n2; } public static int Compare2 (string s1, string s2 ) { return s1.Length - s2.Length; } } }
7.多播委托
委托可以指向多个函数,但要满足指向的函数必须跟委托具有相同的签名(参数和返回值) 可以使用=
+=
操作
8.lambda表达式
(参数)=>{方法体} => goes to eg:list.RemoveAll(n => n > 4);
//移除大于4的元素
9.使用委托实现窗体传值
代码