VS2015
可以在运行窗口中输入devenv打开VS2015
解决方案:比作公司
项目:比作部门
类:比作员工
引用命名空间
京东----->京东在线商城类----->顾客类
淘宝----->淘宝在线商城类------>顾客类
高端霸气公司------->浩子项目------>顾客类 当需要引用京东顾客类时 需要京东的命名空间
.sln后缀:解决方案文件,里面包含着整个解决方案的信息,可以双击运行。
.csproj后缀:项目文件,里面包含着这个项目的信息,可以双击运行。
Console.WriteLine("要打印的内容");
Console.ReadKey(); //1、暂停当前程序
//2、等待用户按下任意键继续,按下的任意键将显示在控制台上
右键 选择卸载项目 之后可以选择重新加载项目
Ctrl + K + D 快速对齐代码
Ctrl + K + C 注释多行代码
Ctrl + K + U 取消注释代码
#region
#endregion 折叠冗余代码 可以在隔一个空之后添加注释
C#额外数据类型:金钱类型 规范语法:decimal money = 5000m;
Datatime 日期数据类型
精度可以达到28到29位
C# String 一个是公有的数据类型
string是独属于C#的数据类型 建议使用
和其他编程语言的命名规则大同小异 严格区分大小写 与Java不一样的是不能以$开头 只能以字母开头
两个命名规范:
使用方法:先挖个坑,再填个坑。
int n1 = 10;
int n2 = 20;
Console.WriteLine("第一个数字是:{0},第二个数字是:{1}",n1,n2);
Console.ReadKey();
使用占位符的注意事项:挖了几个坑,就填几个坑。多填没有效果。少填会抛异常
占位符按照挖坑的顺序输出
int n1 = 10;
int n2 = 20;
n1 = n1 - n2;
n2 = n1 + n2;
n1 = n2 - n1;
Console.WriteLine("请输入您的姓名:");
string name = Console.ReadLine();
\”:表示一个英文半角的双引号;
\b:表示一个退格键 在句子前后使用没有效果
\r\n:windows操作系统不认识\n,只认识\r\n;
\\:表示一个\;
@:
自动类型转换:小变大
强制类型转换:大变小
语法:数据类型 变量 = (待转换类型)原类型变量
PS:如果需要输出两位小数的数据时:可以如下输出
Console.WriteLine(“{0:0.00}”,d);
Console.ReadKey();
PS:类型如果相兼容的两个变量,可以使用自动类型转换或者强制类型转换,但是如果两个类型的变量不兼容,比如string---->int 或者string--->double类型的转换,我们可以使用一个叫做Convert的格式转换工厂进行转换。
string s = "123";
double s1 = Convert.ToDouble(s);
Console.WriteLine(s1);
Console.ReadKey();
int d = Convert.ToInt32(s);
Console.WriteLine(d);
Console.ReadKey();
15、异常捕获
我们在程序中经常会出现各种各样的异常,你如果想要你的程序变得坚强一些,在你的代码中应该经常性的使用try-catch来进行异常捕获。
语法:
try{
可能会出现异常的代码;
}catch{
出现异常后要执行的代码;
}
执行过程:如果try中的代码没有发生异常,那么catch中的代码不会执行
如果try中的代码出现了异常,哪怕这行出现异常的代码后面还有一百行代码都不会再继续执行,而是直接跳到catch中执行代码。
调试方法:
打出for按两下tab键
//产生随机数
//1、创建能够产生随机数的对象
//2、让产生随机数的这个对象调用方法来产生随机数
Random r = new Random();
int number = r.Next(1, 11); //左闭开区间
Console.WriteLine(number);
Console.ReadKey();
21、素数算法
for (int i = 2; i <= 100; i++) //起到循环作用
{
bool b = true; //定义到里面的原因是因为当i到4时,b=false 就没有机会变成true
for (int j = 2; j < i; j++)
{
//除尽了说明不是质数,也就没有再往下继续取余的必要了
if(i % j == 0)
{
b = false;
break;
}
}
if (b)
{
Console.WriteLine(i);
}
}
Console.ReadKey();
}
常量语法:const 变量类型 变量名 = 值;
语法:
[public] enum 枚举名 {
值1,
值2,
值3,
……………
}
将枚举声明到命名空间的下面,类的外面,表示这个命名空间下所有的类都可以使用这个枚举。
#region 将枚举类型强转成int类型
//Seasons s = Seasons.春;
//QQState q = QQState.Busy;
////枚举类型默认可以跟int类型互相转换 枚举类型跟int类型是兼容的
//int n = (int)q;
//Console.WriteLine(n);
//Console.WriteLine((int)QQState.Leave);
//Console.ReadKey();
#endregion
#region 将int类型强转成枚举类型
int n1 = 3;
QQState state = (QQState)n1;
Console.WriteLine(state);
Console.ReadKey();
#endregion
所有的类型都能够转换成string类型 调用ToString();
枚举类型默认是跟int类型相互兼容的,所以可以通过强转进行类型转换的语法互相转换。当转换一个枚举中没有的值的时候,不会抛异常,而是直接将数字显示出来。
枚举同样也可以跟string类型互相转换,如果将枚举类型转换成string类型,则直接调用ToString()
如果将字符串转换成枚举类型则需要下面一行代码:
(要转换的枚举类型)Enum.Parse(typeof(要转换的类型),“要转换的字符串”);
如果转换的字符串是数字,则就算枚举中没有,也不会抛异常
如果转换的字符串是文本,如果枚举没有,就会抛异常
#region 将枚举类型强转成int类型
//Seasons s = Seasons.春;
//QQState q = QQState.Busy;
////枚举类型默认可以跟int类型互相转换 枚举类型跟int类型是兼容的
//int n = (int)q;
//Console.WriteLine(n);
//Console.WriteLine((int)QQState.Leave);
//Console.ReadKey();
#endregion
#region 将int类型强转成枚举类型
//int n1 = 3;
//QQState state = (QQState)n1;
//Console.WriteLine(state);
//Console.ReadKey();
#endregion
语法:
[public] struct 结构名
{
成员名;//字段
}
变量在程序运行期间只能存储一个值,而字段可以存储多个值。
区别字段与变量命名
字段:_name;
语法:
数组类型 [] 数组名 = new 数组类型[数组长度]
int 数组初值为0
string数组初值为null
bool数组初值为false;
int[] nums = {1,2,3,4};
判定最大值最小值方法:
int max = nums[0];
//第二种写法:int max = int.MinValue;
// int min = int.MaxValue;
int min = nums[0];
就是将一个数组中的元素按照从大到小或者从小到大的顺序进行排列
int[] nums = {9,8,7,6,5,4,3,2,1,0}
第一趟比较;8,7,6,5,4,3,2,1,0,9 交换了9次 i=0 j=nums.length-1-i
第二趟比较;7,6,5,4,3,2,1,0,8,9 交换了8次 i=1 j=8
第三趟比较;6,5,4,3,2,1,0,7,8,9 交换了7次i=2 j=7
第四趟比较;5,4,3,2,1,0,6,7,8,9 交换了6次
.
.
.
第九趟比较;0,1,2,3,4,5,6,7,8,9 交换了1次
for(int i=0;i
{
for(int j=0;j
{
if(nums[j]>nums[j+1]){
string temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
升序方法:Array.sort(nums);
反转方法:Array.Reverse(nums);
public static 返回类型 方法名([参数列表]){
方法体;
}
C#中没有全局变量概念,使用静态字段模拟全局变量,声明格式:public static int _num = 10;声明位置:在类中方法外声明
要求在方法内部进行赋值
如果你在一个方法中,返回多个相同类型的值的时候,可以考虑一个数组。
但是返回多个不同类型的值的时候,返回数组就不行了,可以考虑使用out参数。
要求在方法外部必须赋值,而在方法内不用赋值1
能够将一个变量带入一个方法中进行改变,改变完成后再将改变后的值带出方法。
将参数列表中跟可变参数数组类型一致的元素都当做数组的元素去处理。
Params可变参数必须是形参列表中的最后一个参数
方法自己调用自己
找出一个文件夹中所有的文件
32 类的语法
public class 类名
{
public 数据类型 字段名
}
创建这个类的对象过程称之为类的实例化
使用关键字new
this.表示当前这个类的对象
类是不占内存的,而对象是占内存的
属性:保护字段,对字段的赋值和取值进行限定
属性的本质就是两个方法,get方法和set方法
Fields:字段
Methods:方法
Property:属性
public string Name
{
get {
判断_name
return _name}
set {_name = value
判断value
}
}
给属性赋值调用属性的set方法 取值调用get方法
不直接给字段赋值 而应该给属性进行赋值
不直接从字段取值,而应该在属性进行取值
因此字段就不声明为public 默认为private 作用范围仅限该类中
当我们创建好一个类的对象后,需要给这个对象的每个属性去赋值。我们管这个过程称之为对象的初始化。
静态与非静态的区别
静态成员必须使用类名调用
非静态成员使用对象调用
静态方法中仅允许访问静态成员 不允许访问非静态成员
静态类中仅允许出现静态成员 不需要创建对象
使用:
释放资源。
GC Garbage Collection 垃圾回收器
构造函数帮我们初始化对象 给对象的每个属性依次赋值
构造函数没有返回值,连void也没有
构造函数的名称必须和类名一样
~类名(){
}
程序结束的时候才使用 帮助我们释放资源
C#也有垃圾回收器自动释放资源
用于解决类重名问题
Alt+shift+F10 或者记住它
在一个项目中引用另一个项目的类
区别:1、内存上存储的地方不一样
值类型我们称之为值传递,引用类型我们称之为引用传递
值类型:基本数据类型 值存储在内存中的栈中
引用类型:string、自定义类、数组
值存储在内存中的堆中
字符串的不可变性
当给一个字符串重新赋值之后,老值没有销毁,而是重新开辟一块空间存储新值
当程序结束后,GC扫描整个内存,如果发现有的空间没有被指向,则立即被垃圾回收器回收掉
String可以看成char类型的一个只读数组
可以通过下标去访问字符串的某一个元素
string s = “abc”;
先转换成char类型 char c = s.ToCharArray();
c[0] = ‘b’;
将字符数组转换为字符串
s = new string(c); //创建一个字符串对象 能够将字符数组转化为字符串
stringBuilder
//处理大量字符串运算时使用stringBuilder函数
StringBuilder sb = new StringBuilder();
//string str = null;
Stopwatch sw = new Stopwatch();
sw.Start();//开始计时
for (int i = 0; i < 10000; i++)
{
//str += i;
//调用方法
sb.Append(i);
}
sw.Stop();//结束计时
//最后将StringBuilder转换成字符串
Console.WriteLine(sb.ToString());
Console.WriteLine(sw.Elapsed);
Console.ReadKey();
字符串的各种方法:
忽略字符串大小写:s.equals(st,stringComparision.ordinalIgnoreCase)
可以先定义一个字符数组char[] c = {‘’,‘’}
然后可以调用s.spilt(c);
此时会把分割出来字符自动用空代替 可以添加属性去掉
s.spilt(c,StringSpiltOptions.RemoveEmptyEntries);
6、字符串替换方法:s.replace(string oldValue,string newValue);
7.截取字符串:string s = s.Substring(…);
8、判断字符串中是否含有子串:bool Contains(string value)
9、bool StartWith(string value):判断字符串是否以子串value开始
bool EndsWith(string value):判断字符串是否以子串value结束
10、int indexOf(…):判断字符串第一次出现的位置 找不到返回
-1
11、int lastIndexOf(…):找到最后一个出现字符的位置
12 string trim():去掉字符串前面和后面出现的空格
去掉前面空格:string TrimStart();
去掉后面空格:string TrimEnd();
13 string.isNullOrEmpty()如此调用
14、string Join();
36 继承
把这几个类当中重复的成员单独的拿出来封装成一个类,作为这几个类的父类。
子类没有继承过来父类的私有字段 只继承了父类的属性和方法
继承的两个特性:
继承的单根性:一个子类只能有一个父类
继承的传递性:可以传递下去
查看类图:
单击项目名称--->右键点击查看—>查看类图
Ps:子类并没有继承父类的构造函数,但是,子类会默认的调用父类无参的构造函数。用来创建父类的对象,使得子类使用父类的成员
所以如果在父类中重新写了一个有参数的构造函数之后,那个无参数的就被去掉了,子类就调用不到了,所以子类会报错
解决办法:
Ps:object是所有类的基类
隐藏后果就是子类调用不到的父类成员public new void sayHello()
如果一个地方需要一个父类作为参数,我们可以给一个子类代替
Person p = new Student();
Student ss = (Student)p;
if(p is Teacher){
Teacher tt = (Teacher)p;
tt.TeacherSayHello();
}
else{
Console.WriteLine(“转换失败!”);
}
as 表示类型转换,如果能够转换则返回对应的对象,否则返回一个NULL
Teacher tt = p as Teacher;
受保护的:可以在当前的类的内部以及该类的子类中使用
arrayList的长度问题
count表示这个集合中实际包含的元素的个数
capcity表示这个集合可以包含的元素的个数
如果count>capcity,集合就会向内存中申请多开辟一倍的空间来保证集合的长度一直够用
40 HashTable 键值对集合
Foreach循环 tab双击
Foreach(var item in collection){
}
containsKey();
clear();
remove(键值);
var:根据值能够推断出来类型
键值对集合必须保证键唯一 值可重复
41 path类 using System.IO
42 File类
File.Create(路径);
删除文件
File.Delete(路径);
复制文件
File.Copy(复制的路径名,新的路径名);
读取文件的数据
File.ReadAllBytes(@“路径名”)
//Encoding.Default.GetString(字节数组) 解码方法
//Encoding.UTF-8.GetString()
//Encoding.GetCoding(“GB2312”).GetString();
追加文件
File.AppendAllText(路径名,“文本内容”);
写入数据
string str = “你好”
Byte[] buffer = Encoding.Default.GetBytes(str)
File.WriteAllBytes(@“路径名”,buffer);
编码:
Director类
Directory.Exists(路径名);
Directory.CreateDirectory(路径名);
Directory.Move();
Directory.getDirectories(路径名)
Directory.GetFiles(路径名,“*.txt”);
43 文件流
FileStream:操作字节的
FileStream fsRead = new FileStream(@"C:\Users\Administrator.USER-20180224BZ\Desktop\特点的.txt",FileMode.OpenOrCreate,FileAccess.Read);
byte[] buffer = new byte[1024 * 1024 * 3];//表示每次读3M
//r就是本次实际读取到的有效字节数
int r = fsRead.Read(buffer, 0, buffer.Length);
//将字节数组转换成字符串
string str = Encoding.Default.GetString(buffer,0,r);
//文件流GC不会释放内存
Console.WriteLine(str);
fsRead.Close();
fsRead.Dispose();
Console.ReadKey();
//使用FileStream来写入数据
using (FileStream fsWrite = new FileStream(@"C:\Users\Administrator.USER-20180224BZ\Desktop\new.txt", FileMode.OpenOrCreate, FileAccess.Write))
{
string s = "今天天气真好啊!";
byte[] buffer = Encoding.Default.GetBytes(s);
fsWrite.Write(buffer, 0, buffer.Length);
Console.WriteLine("写入成功!");
}
Console.ReadKey();
复制文件
static void CopyFile(string sourse,string target)
{
using (FileStream fsRead = new FileStream(sourse, FileMode.OpenOrCreate, FileAccess.Read))
{
using (FileStream fsWrite = new FileStream(target, FileMode.OpenOrCreate, FileAccess.Write))
{
byte[] buffer = new byte[1024 * 1024 * 5];//每次读5M
while (true)
{
int r = fsRead.Read(buffer, 0, buffer.Length);
if(r == 0)
{
break;//读取完了
}
fsWrite.Write(buffer, 0, r);
}
}
}
}
}
}
使用using的好处,可以自动释放字节流和字符流的内存
StreamReader,StreamWriter:操作字符的
//读取数据
using (StreamReader sr = new StreamReader(@"C:\Users\Administrator.USER-20180224BZ\Desktop\特点的.txt",Encoding.Default))
{
while (!sr.EndOfStream)
{
Console.WriteLine(sr.ReadLine());
}
Console.ReadKey();
}
//写入数据
using (StreamWriter sw = new StreamWriter(@"C:\Users\Administrator.USER-20180224BZ\Desktop\new.txt"))
{
sw.WriteLine("今天天气好晴朗!");
}
Console.ReadKey();
//list
List < string > list = new List<string>();
list.Add("张三");
list.Add("李四");
list.AddRange(list);
//for (int i = 0; i < list.Count; i++)
//{
// Console.WriteLine(list[i]);
//}
foreach (string item in list)
{
Console.WriteLine(item);
}
Console.ReadKey();
//Dictionary
//统计welcome to China中每个字符出现的次数
string st = "welcome to China";
Dictionary<char, int> dic = new Dictionary<char, int>();
for (int i = 0; i < st.Length; i++)
{
if(st[i] == ' ')
{
continue;
}
if (!dic.ContainsKey(st[i]))
{
dic.Add(st[i], 1);
}
else
{
dic[st[i]]++;
}
}
foreach (KeyValuePair<char,int> kv in dic)
{
Console.WriteLine("字母{0}出现了{1}", kv.Key, kv.Value);
}
Console.ReadKey();
44 装箱和拆箱
装箱:就是将值类型转换为引用类型
装箱操作会影响代码性能,因为在不断的进行类型转换,所以在程序中应该尽量避免多使用装箱操作。
拆箱:将引用类型转换为值类型
看两种类型是否发生了装箱或者拆箱,要看这两种类型是否存在继承关系,才有可能会有装箱或者拆箱操作
45 多态
让一个对象能够表现出多种状态
//比较low的做法
Chinese cn1 = new Chinese("韩梅梅");
Chinese cn2 = new Chinese("李蕾");
Japanese j1 = new Japanese("树下军");
Japanese j2 = new Japanese("经辫子");
Person[] pers = { cn1, cn2, j1, j2 };
for (int i = 0; i < pers.Length; i++)
{
if(pers[i] is Chinese)
{
((Chinese)pers[i]).SayHello();
}
else if(pers[i] is Japanese)
{
((Japanese)pers[i]).SayHello();
}
else
{
Console.WriteLine("转换失败!");
}
}
Console.ReadKey();
多态的实现方法:1、虚方法 2、抽象类 3、接口
即可实现如下效果:
Chinese cn1 = new Chinese("韩梅梅");
Chinese cn2 = new Chinese("李蕾");
Japanese j1 = new Japanese("树下军");
Japanese j2 = new Japanese("经辫子");
Person[] pers = { cn1, cn2, j1, j2 };
for (int i = 0; i < pers.Length; i++)
{
pers[i].SayHello();
}
Console.ReadKey();
当父类中的方法不知道如何去实现的时候,可以将父类写成抽象类,可以将方法写成抽象方法。
abstract class Animal
{
public abstract void Bark(); //没有方法体
抽象类不允许创建对象
}
Animal a = new Dog();
a.Bark();
Console.ReadKey();
子类继承抽象类后,必须把父类的所有抽象成员都重写。
除非子类也是一个抽象类,则可以不重写。
抽象类中可以包括非抽象的成员。并且可以不需要被子类重写实现。
抽象类是有构造函数,虽然不能被实例化。
如果父类的抽象方法中有参数,那么继承这个抽象父类的子类在重写父类的方法时必须传入对应的参数。
如果有返回值,那么子类也有返回值。
如果父类中的方法中有默认的实现,并且父类需要被实例化,这时可以考虑将父类定义成一个普通类,用虚方法实现多态。
在抽象类中可以定义一个虚方法,子类可以不重写。但没多大意义。
46 访问修饰符
Public:公开的公共的
Private:私有的,只能在当前类的内部访问
Protected:受保护的,只能在当前类的内部以及该类的子类中能够被访问。
能够修饰类的访问修饰符只有两个:public 和 internal
Internal:只能在当前项目中访问,默认为internal
在同一个项目中,internal和public的权限是一样的。
Protected internal:protected+internal的权限
可访问性不一致:
要求子类的访问权限不能高于父类的访问权限,会暴露父类的成员。
47 简单工厂设计模式
模式:设计这个项目的一种方式。
///
/// 简单工厂的核心,根据用户的输入创建对象赋值给父类
///
/// brand">用户输入的品牌
///
public static NoteBook GetNoteBook(string brand)
{
NoteBook nb = null;
switch (brand)
{
case "Lenovo":
nb = new Lenovo();
break;
case "Acer":
nb = new Acer();
break;
case "Dell":
nb = new Dell();
break;
}
return nb;
}
48、值传递和引用传递
值类型在复制的时候,传递的是这个值的本身。
引用类型在复制的时候,传递的是对这个对象的引用。
序列化:就是将对象转换成二进制。
反序列化:就是将二进制转换为对象。
作用:传输数据。
[Serializable] //加上Serializable
class Person
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
2、//要将p这个对象传输给电脑
Person p = new Person();
p.Name = "张三";
using (FileStream fsWrite = new FileStream(@"C:\Users\Administrator.USER-20180224BZ\Desktop\111.txt", FileMode.OpenOrCreate, FileAccess.Write))
{
//开始序列化对象
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fsWrite, p);
}
Console.WriteLine("序列化成功!");
Console.ReadKey();
3、//接收对方发来的二进制 反序列化
Person p;
using(FileStream fsRead = new FileStream(@"C:\Users\Administrator.USER-20180224BZ\Desktop\111.txt", FileMode.OpenOrCreate, FileAccess.Read))
{
BinaryFormatter bf = new BinaryFormatter();
p = (Person)bf.Deserialize(fsRead);
}
Console.WriteLine(p.Name);
Console.ReadKey();
49 部分类
关键字:partial eg:public partial Class Person{}
这样可以在项目中定义相同类名的类,而且类中定义的成员共享。
不可以定义同名方法,除非重载
50 密封类
关键字:sealed
eg:public sealed class Person{}
密封类:不能被继承,但可以继承其他类。
51 重写父类的ToString()
ToString()方法是object的虚方法
子类可以重写父类的虚方法
52 接口
接口就是一种规范或者说是一种能力。
只要继承了该接口,就必须实现这个接口中的所有成员。
接口语法:
Public interface I..able
{
成员;
}
接口中的成员不允许添加访问修饰符,默认就是public
没有方法体。接口中不能包含字段。可以有属性,可以有索引器以及时间,不能有“字段”和构造函数。
为了多态,接口不能实例化。
不能实例化:抽象类,接口,静态类。
要写实现多态,可以指向一个子类对象
接口与接口之间可以继承,并且可以多继承。
接口不能继承类,但是类可以继承类和接口
一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA的前面。
显示实现接口就是为了解决方法中的重名问题
Void IFlyable.Fly(){} //强调这个方法是接口中的方法
使用虚方法实现的多态:抽象出来父类,共有方法可以写。并且需要创建父类的对象,反之,使用抽象类来实现多态。
使用接口实现多态:抽象不出来父类,但是都有一个共同的行为。
53 GUID:产生一个不会重复的编号
54 MD5
将字节数组转换成字符串
55、Directory静态类
命名空间:using System.IO
创建文件夹:Directory.CreateDirectory(@"C:\a");
删除文件夹:Directory.Delete(@"C:\a");
Ps:如果文件夹不是空的,则会抛异常;解决办法就是添加一个bool参数
剪切文件夹:Directory.Move(@"C:\a", @"C:\Users\Administrator.USER-20180224BZ\Desktop\new");
获得指定文件夹所有文件的全路径:string[] path = Directory.GetFile(路径名,”*.txt”);
获得指定文件夹所有文件夹的全路径:string【】 path = Directory.GetDirectories(路径名);
判断指定的文件夹是否存在:Directory.Exists(路径名);