1.背景 ,所在的专业是 软件工程net方向,所以在2013年就开始学习C#语言,那时候就会写个小程序,比如贪吃蛇什 么的,后接触了网站,觉得很有趣,就开始加强基础学习。
2.在2014年寒假在广州打工的时候,对基础加强进行了学习!后总结成了word文档,但十分不方便,就在此补上总 结。
面向对象:
(1)封装:尽量减少代码冗余度,减少重复代码
(2)多态: 一个对象有不同的表现
(3)继承:继承用在多个地方,可以用在抽象类、接口等
关键字为 :(冒号)
(4) 字段:结构体中 构造函数的字段需要全部实现,否则报错
(5)属性:get set 的读写功能,同时可以对字段的属性进行限制比如:性别只有男女
代码示例:
private string name;
public string Name
{
get{return name;}
set{name=value;}
}
不过现在有更简单的实现:
private string name{get;set}
(1)继承:
继承的使用往往伴随着多个类的使用,不仅仅是父类和子类的使用,还有实现的功能;
在抽象类和接口中经常使用来实现;
(2) 这里要注意两个关键字 this 和 base:
this 是代表当前类,可以指示当前类,而base代表的是父类,base有几个用处,首先是可以表明父类的引用,其次是在构造函数是 可以直接继承父类的构造函数比如:
最后base 还可以调用父类的方法直接 base.方法名 即可
(3)抽象类 :
关键字是abstruct ,抽象类中的抽象方法不能被实现,只能在子类中实现(override):
子类:
classSub : Result
{
public Sub(int numA, int numB):base(numA,numB)
{
}
public override int getResult()
{
return base.NumA - base.NumB;
}
(4)虚方法:关键字virtual ,可以实现,也可在子类中实现,若调用则使用子类中的实现;
(1)抽象类:
抽象类的使用可以减少代码量,同时可以减少不必要的重复,使用起来方便,注意在实现时,也可以使用构造函数的实现(base);
(2)接口:
关键字 :interface,接口定义后不可以实现,只可以在子类中实现方法,同时不能声明接口方法时,不能用修饰符,一般声明为: 返回值 方法名(参数);
接口可以在抽象类中实现,不过抽象类还要在子类中实现,若在子类中实现,则同时抽象类和接口可以同时实现此子类。
(3)as :表示转化 比如person类和student类,在person类中判断是不是student类时
可以写成 person as student 则进行转换,如果是则返回student类是存在的对象 ,不是则student类是null。
is :则可以判断是否是返回bool类型 ,比如bool tmp=person is student;
(4)工厂模式:
抽象类和接口在实现的时候,需要创建子类,这个时候就用到了简单的工厂模式,来造类,同时可以判断条件来造类。
比如:
class Fectory
{
public static ResultCreateInstence(string type,int numA,int numB)
{
Result r = null;
switch (type)
{
case "+":
r = new Add(numA, numB);
break;
case "-":
r = new Sub(numA, numB);
break;
default:
throw new Exception("符号不对");
break;
}
return r;
}
}
当然在使用类在使用的时候可以返回,在使用接口的时候,用的比较多。
(5)集合 泛型 字典 的使用
(1) File类
快速读取文件内容:string[] strs= File.ReadLines(@“D:/abc.txt”,Encoding.Default).toArray();
(2) System.IO: 文件夹创建 、删除 和 判断。(Directory类)
文件的创建 、删除 和 判断。(File类)
Path类:比较重要,使用广泛
(3)Stream
文件流操作(1)FileStream读取文件:
Using(FileStrem fs=newFileStream(@“D:/abxc.txt”,FileMode.Open))
{
Byte[] buffer=new byte[1024];
Int n;
While((n=fs.Read(buffer,0,1024)))>0)
{
Console.WriteLine(Encoding.Default.getString(buffer,0,n));
}
}
Using(FileStream fs=File.OpenRead(@“D:/abc.txt”))
{
//同上
}
文件流操作(2)FileStream创建文件:
string str=”创建文件内容”;
Using(FileStream fs=new FileStream(@”D:/abc.txt”,FileMode.Open))
{
byte[] buffer=Encoding.Default.GetBytes(str);
fs.write(buffer,0,buffer.Lenth);
}
Using(FileStreamfs=File.OpenWrite(@”D:/abc.txt”))
{
//同上
}
(1). StreamReader StreamWriter
StreamReader读取文件(1):
Using(FileStream fs=new FileStream(@”D:/abc.txt”,FileMode.OPen))
{
Using(StreamReader sr=new StreamReader(fs))
{
sr.Read();
}
}
Using(StreamReader sr=newStreamReader(@“D:abc.txt”))
{
String line;
While((line=sr.read())!=null)
{
Console.writeLine(line);
}
}
StreamReader存文件(2):s
Using(FileStream fs=new FileStream(@”D:/abc.txt”,FileMode.Create))
{
Using(StreamWriter sr=new StreamWriter(fs))
{
sr.write();
}
}
这两个类使用的时候需要灵活应用,微软已经封装好了一切,使用起来很简单。
(2). 序列化,反序列化,文件监控FileSystemContorl
监控文件夹,代码示例:
//夸线程操作
Control.CheckForIllegalCrossThreadCalls=false;
FileSystemWatcher fsw = newFileSystemWatcher();
fsw.Path = @"D:\";
fsw.Filter = "*.txt";
fsw.IncludeSubdirectories = true;
fsw.Created += fsw_Created;
fsw.EnableRaisingEvents = true;
}
void fsw_Created(object sender,FileSystemEventArgs e)
{
listBox1.Items.Add(e.Name +"文件夹监控"+e.GetType());
}
序列化和反序列化:
首先引入命名空间:
usingSystem.Runtime.Serialization.Formatters.Binary;
序列化之前需要标明可序列话:在类上方标明 [Serializable]
代码示例如下:
private static void Deserialize()
{
using (FileStream fs = newFileStream(@"D:\abc.txt", FileMode.Open))
{
BinaryFormatter bf = newBinaryFormatter();
student bfs =bf.Deserialize(fs) as student;
if (bfs != null)
{
bfs.say();
}
}
}
private static void Serialize(students)
{
using (FileStream fs = newFileStream(@"D:\abc.txt", FileMode.Create))
{
BinaryFormatter bf = newBinaryFormatter();
bf.Serialize(fs, s);
}
}
(3). 正则表达式 (重点但需要常练习)
元字符
. 匹配任意单个字符
* 0或多次
+ 一或多次
? 0或一次
[] 匹配[]中的字符出现一次[0-9] [a-zA-Z]
() 改变正则优先级 (zo)+ zo出现1或多次
| 或 z|food 匹配z或food (z|f)ood 匹配 zood或food
{n} 出现n次
{n,} 至少出现n次,最多不限
{n,m} 至少出现n次,最多出现m次
^ 以谁开头 取反[^>]
$ 以谁结尾
\d 数字
\D
\w 字母 数字 _ 汉字
\w
\s 空白
\S
Regex.IsMatch 字符串匹配
Regex.Match 字符串提取
Regex.Matches 提取多个匹配结果
Regex.Replace 正则替换 分组替换
Match
MatchCollection
RegexOptions
当行模式 Single line 让正则表达式的.能匹配到\n
多行模式 Multiline ^$ 匹配每一行的内容
(1) 复习
(2) 匹配字符串
1. 将网页上的文章获得下来
参照下面方法:
private static void RegexString()
{
//根据流来提取字符串
//爬取网页上的文字,并输出和写入txt文件
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(@"http://localhost:51654/网络爬虫_百度百科.htm");
using (StreamReader sr = new StreamReader(stream))
{
using (StreamWriter sw = newStreamWriter(@"D:/yuan/网络爬虫.txt"))
{
string content =sr.ReadToEnd();
MatchCollection matchs =Regex.Matches(content, @"(?.+?)
2.流下载图片
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(@"http://localhost:51654/网络爬虫_百度百科.htm");
using (StreamReader sr= new StreamReader(stream))
{
string html = sr.ReadToEnd();
MatchCollection matchs =Regex.Matches(html,@"src=""(?.+?)"">");
foreach (Match match in matchs)
{
string imgPath="http://localhost:51654/" +match.Groups["img"].Value;
string imgName =Path.GetFileName(imgPath);
wc.DownloadFile(imgPath,imgName);
}
}
(3) 总结
System.IO多加练习,加强记忆。
(1) Xml的创建和读取
Xmldocument doc=newXmldocument();
注意这两个doc.save(); |doc.load(); 方法来保存xml和读取xml的内容。
(2) 枚举
关键字enum
声明后,直接可以通过 枚举名.内容 来取得值。
(3) 结构体
声明 struct 结构名 ,相对类来说和类同级,没有无参的构造函数,给字段传参时,需要将所有的字段传参,可用new关键字,也可不用。
(1)类库的使用
类库的使用,在拓展应用时,用处方便,写好后,可以直接调用!
(2)程序集
(3)反射
Assembly
(4)采集程序
复习IO和Regex(正则表达式)的使用
(1)线程
当应用程序开启后,只有一条UI线程(主线程)。
(2) 多线程
多线程的使用涉及到委托的使用,所以在要将委托复习和巩固。
多线程里要将执行的代码程序封装成方法,将方法名给子线程,然后执行,可以有参数,也可以没有参数。
Thread thread=new Thread(方法名);
thread.isBackGround=true;//设置成后台线程为了让关闭程序后,该线程自动结束而设置。
thread.start();
(3)线程Lock
给在线程中执行的代码加Lock后,使得该方法在被多个子线程调用的时候,cpu分配上不冲突。
(4)Socket 网络编程
Socket 编程(套接字),在这里只学习了流式/tcp的使用。首先是命名空间
Using System.Net.Sockets;
Using system.Net;
在声明的时候,如下:
//声明,方式为流式,类型为Tcp
Socket connSoc = newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//设置IP地址
IPAddress ipaddress =IPAddress.Parse(ComConst.ipAddress);
//设置端口号
IPEndPoint ipPoint = newIPEndPoint(ipaddress, ComConst.ipPort);
//将IPEndPoint添加到Socket当中
connSoc.Bind(ipPoint);
//设置监听数
connSoc.Listen(10);
lb_tishi.Text += "服务器启动成功";
下面将循环进行监听客户端的连接,需要在子线程中进行,否则会阻塞主线程
while (userConn)
{
//Accept()方法返回一个Socket
Socket userSoc = connSoc.Accept();
//获得客户端的ip和端口
EndPoint ep=userSoc.RemoteEndPoint;
ShowMsg("登陆成功");
}
//发送字节数组
userSoc. Send(byte[]buffer);
接受字节数组,在接收的时候,需要在子线程中进行,否则会阻塞UI线程
最好用循环来使用,否则只能接收一条信息
while (userRecv)
{
byte[] buffer = newbyte[1024];
userSoc.Receive(buffer);
string msg = Encoding.UTF8.GetString(buffer);
showMsg(msg);
}