20050801
namespace ConsoleApp_Test
{
class Program
{
static void Main(string[] args)
{
Guid gene1 = new Guid();
CopyMan cm1 = new CopyMan(gene1);
CopyMan cm2 = new CopyMan(gene1);
bool b = cm1.Equals(cm2);
HashSet<CopyMan> hs = new HashSet<CopyMan>();
hs.Add(cm1);
Console.WriteLine(hs.Contains(cm1));//因为复制人cm1与cm2是同一基因(即cm1与cm2属于同一实体),所以cm1加入到hs,cm2也就加入到了hs
Console.WriteLine(hs.Contains(cm2));
Console.ReadKey();
}
}
/// <summary>
/// 变种人之复制人:一个复制人可以复制成多个,而且每个都可以易容,区分它们是否属于同一实体的只能依据基因(即guid)
/// </summary>
public class CopyMan
{
public Guid Gene { get; private set; } //变种人的基因在外部是不可以更改的,所以是private set
public CopyMan(Guid gene)//产生一个复制人必须需要基因
{
Gene = gene;
}
//重写Equals()时,必须重写GetHashCode(),GetHashCode()的返回值用来作为两个对象是否属于同一个实体的依据.
public override bool Equals(object cm)
{
if (cm == null) return false;
if (!(cm is CopyMan)) return false;
return this == (CopyMan)cm; //此处的==操作符是重写的操作符
}
public override int GetHashCode()
{
return Gene.GetHashCode();
}
public static bool operator ==(CopyMan cm1, CopyMan cm2)
{
if (cm1 is null && cm2 is null) return true;
if (cm1 is null || cm2 is null) return false;
return cm1.Gene == cm2.Gene;
}
public static bool operator !=(CopyMan cm1, CopyMan cm2)
{
return !(cm1 == cm2);
}
}
}
20050801
C# == 与Equals()
1.在比对值类型时,如果二者值相等,则返回true,否则返回false。
2.在比对引用类型时,如果二者引用的是同一个对象,则返回true,否则返回false。
3.Equals()方法,在不重写的情况下,与没区别。
4.微软重写了string的Equals()方法,使得这个方法比对的是string的字符串内容,同时也重载了运算符,使得string在进行==比对时,得到的结果与Equals()相同,即比对字符串内容
20050601
20042601
不同编码方式每个文字字符得到的字节数目不一样,为了防止乱码,要选择合适的编码方式进行读写操作//一个汉字字符通过ASCII编码占一个字节;UTF-8:三个字节;UTF-32:四个字节
string s = "今天天气好晴朗";
byte[] buffer0 = System.Text.Encoding.ASCII.GetBytes(s);//每个字会占一个字节
byte[] buffer1 = System.Text.Encoding.UTF8.GetBytes(s);//每个字会占三个字节
byte[] buffer2 = System.Text.Encoding.UTF32.GetBytes(s);//每个字会占四个字节
byte[] buffer3 = System.Text.Encoding.Default.GetBytes(s);//默认方式,英文数字一个字节,中文三个字节
File.WriteAllBytes(@"C:\Users\宋宝涛\Desktop\1.txt",buffer1);//由于要将文字写入.txt文件(.txt文件是UTF-8编码),所以此处选择buffer1
//不同的文字需要使用不同的编码方式,但图片、视频等就不需要进行编码了,可以直接使用File.ReadAllBytes()读取文件
File读取操作
//乱码的原因就是文件保存的编码方式与文件打开的编码方式不一致
//File这个类只能用来读取文本文件。 文本文件:拖进记事本里不出现乱码的就是文本文件。 .doc不是文本文件
byte[] buffer = File.ReadAllBytes(@"C:\Users\宋宝涛\Desktop\1.txt"); //byte字节也是一个数据类型,是二进制数据类型。1024byte=1kb 1024kb=1M
string s = System.Text.Encoding.Default.GetString(buffer); //将二进制数据解码成字符串 Default会自动匹配适合的编码方式
//使用utf-8编码时一个英文字母或者数字占用一个字节,一个汉字占用三个字节
string[] ss = File.ReadAllLines(@"C:\Users\宋宝涛\Desktop\1.txt",System.Text.Encoding.UTF8);
foreach (var n in ss)
{
Console.WriteLine(n);
}
string sss = File.ReadAllText(@"C:\Users\宋宝涛\Desktop\1.txt", System.Text.Encoding.UTF8);
Console.WriteLine(sss);
//其中File.ReadAllBytes()方法可以对文本、图片、音频等读取,而File.ReadAllLines()、File.ReadAllText()只能对文本文件进行读取
File写入操作
string s = "今天天气好晴朗";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(s);
File.WriteAllBytes(@"C:\Users\宋宝涛\Desktop\1.txt", buffer);
string[] ss = { "今天", "天气", "好晴朗" };
File.WriteAllLines(@"C:\Users\宋宝涛\Desktop\1.txt", ss, System.Text.Encoding.UTF8);
string sss = "今天天气好晴朗";
File.WriteAllText(@"C:\Users\宋宝涛\Desktop\1.txt", sss, System.Text.Encoding.UTF8);
//其中File.WriteAllBytes()方法可以对文本、图片、音频等写入,而File.ReadAllLines()、File.ReadAllText()只能对文本文件进行写入
20042602
文件和流
输入流:以文件为源,内存为目的. 输出流:以内存为源,文件为目的.
FileStream是操作字节(最小的存储单元)的,所以FileSteam可以操作任何类型的文件
Stream分为:StreamReader和StreamWriter,他们是用来操作字符的
File也可以用来操作字符,File与Stream的区别在于:File是操作小文件,Stream是操作大文件
FileStream fileStream = new FileStream(@"C:\Users\宋宝涛\Desktop\数据结构.txt", FileMode.Open, FileAccess.Read);
//设置缓冲区(设置内存中缓冲的字节大小)
byte[] buffer = new byte[1024 * 1024];//必须读取到buffer内存中1M数据,才能对buffer内存中的数据进行输出 //对于小文件直接byte[] buffer = new byte[fileStream.Length]全部读取
//参数1:把文件写入到哪个byte[]数组
//参数2:从byte[]数组第几个下标开始读取,一般从0开始
//参数3:最大读取的字节个数
//返回值:实际读到的字节数
int r = fileStream.Read(buffer, 0, buffer.Length);//输入流:从文件写入到内存
Console.WriteLine(r);
string s = System.Text.Encoding.UTF8.GetString(buffer);//输出流:从内存写入到文件
Console.WriteLine(s);
fileStream.Close();
fileStream.Dispose(); //Close与Dispose的区别?using语句块?
Console.ReadKey();
20042701
多媒体读写
public static void DMT(string source,string target)//source:要读取的文件路径;target:要写入的文件路径
{
using (FileStream fss=new FileStream(source, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[1024 * 1024 * 5];
using (FileStream fst=new FileStream(target, FileMode.Open, FileAccess.Write))
{
while (true)
{
int n = fss.Read(buffer, 0, buffer.Length);//会对一直读取,直到文件读取完毕
if (n == 0)
{
Console.WriteLine("写入成功");
return;//break 跳出循环; continue 跳出本次循环; return 跳出方法体
}
else
{
fst.Write(buffer, 0, n);
}
}
}
}
}
20042702
序列化:将对象转换为二进制
反序列化:将二进制转换成对象
目的:在服务端与客户端进行数据传输或将数据存储在硬盘
重要提示:序列化和反序列要求服务端和客户端要有相同的对象
class Program
{
static void Main(string[] args)
{
//序列化(服务端)
Person person = new Person();
Person person1 = new Person();
person.Age = 15;
person.Name = "xiao-wu";
person.Sex = 'F';
//由于FileStream是非托管对象,所以需要使用using释放资源
using(FileStream fs=new FileStream(@"C:\Users\宋宝涛\Desktop\序列化数据.txt",FileMode.Open,FileAccess.Write))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, person);//由于FileStream继承了Stream,根据里氏转换此处可以由子对象fs代替父对象
}
Console.WriteLine("序列化成功");
//反序列化(客户端)
using (FileStream fs=new FileStream(@"C:\Users\宋宝涛\Desktop\序列化数据.txt", FileMode.Open, FileAccess.Read))
{
BinaryFormatter bf = new BinaryFormatter();
person1=(Person)bf.Deserialize(fs);
}
Console.WriteLine(person1.Age+person1.Name+person1.Sex);
Console.WriteLine("反序列化成功");
}
}
[Serializable]//序列化类需要给类标记此特性
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
public char Sex { get; set; }
}
20042801
MD5加密:大家都知道,地球上任何人都有自己独一无二的指纹,这常常成为公安机关鉴别罪犯身份最值得信赖的方法;与之类似,MD5就可以为任何文件(不管其大小、格式、数量)
产生一个同样独一无二的“数字指纹”,如果任何人对文件名做了任何改动,其MD5值也就是对应的“数字指纹”都会发生变化。
public static string Md5(string s)
{
MD5 md5 = MD5.Create();
byte[] buffer = System.Text.Encoding.Default.GetBytes(s);
byte[] newBuffer = md5.ComputeHash(buffer);
StringBuilder sb = new StringBuilder();
for(int i = 0; i < newBuffer.Length; i++)
{
sb.Append(newBuffer[i].ToString("X2"));
}
return sb.ToString();
}
C# ToString(“x2”)的理解
x表示转化为16进制。
2表示输出两位,不足的2位的前面补0
假设有两个数10和26,正常情况十六进制显示A,1A,为了好看可以指定X2,这样显示出来就是0A,1A
大写X:ToString(“X2”)即转化为大写的16进制;小写x:ToString(“x2”)即转化为小写的16进制。
20050201
为什么要使用表单?用于向服务器传输数据,常用于用户注册和登录.
表单里的标签全部都是input标签,只不过是类型可能不同,如<input type=“text/button/radiobutton/reset/checkbox”
<!DOCTYPE html>
<html>
<head>
</head>
<body>//其中的name属性是很重要的
<form action="http://www.baidu.com" method="get">
用户名:<input type="text" name="txtName"/><br/> //服务器是通过name属性获得浏览器提交的数据,所以要想把表单里的数据提交给服务器,表单里相应的一些文本框必须要给
//name属性赋值,即只要想让数据传给服务器,必须给name属性赋值.可以不写name属性通过url看一下有没有将值传到服务器哦
密码:<input type="password'" name="txtPwd" maxLength="6"/><br/>//maxLength是能够输入的最大字符
<fieldset>
<legend>性别</legend> //legend:说明、传奇
男:<input type="radio" name="sex" value="m"/> //单选,name值相同,即为同一组
女:<input type="radio" name="sex" value="f"/><br/>
</fieldset>
婚姻状况:
已婚:<input type="radio" name="married" value="y"/> //单选,name值相同,即为同一组
未婚:<input type="radio" name="married" value="n"/><br/>
爱好:
吃饭:<input type="checkbox" name="favorite" value="eat"/> //多选,name值相同,即为同一组
睡觉:<input type="checkbox" name="favorite" value="sleep"/>
打豆豆:<input type="checkbox" name="favorite" value="beat"/><br/>
选择工作地区:
<select name="workPlace">
<option>河南</option>
<option>西藏</option>
<option>广东</option>
<option>苏州</option>
</select>
<input type="submit" value="提交"/> <input type="reset" value="重置"/>
</form>
</body>
</html>
20050301
HTML框架
<!DOCTYPE html> <!--//框架-->
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<frameset rows="10%,*"> <!--//框架页面不可以有body标签-->
<frame src="Top.html"></frame>
<frameset cols="20%,*">
<frame src="Left.html" ></frame>
<frame name="Main" ></frame> <!--//这里给框架起了个名字-->
</frameset>
</frameset>
</html>
<!DOCTYPE html> <!--//顶部页面-->
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body >
this is top.
</body>
</html>
<!DOCTYPE html> <!--//左侧页面-->
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<a href="https://www.zhihu.com" target="Main">zhihu</a><br />
<a href="https://www.baidu.com" target="Main">baidu</a><br />
<a href="#" target="Main">员工管理</a><br /> <!--//href="#"表示链接到当前页面,其实是无意义的-->
<a href="#" target="Main">系统管理</a>
</body>
</html>
20050302
HTML布局
大多数 HTML 元素被定义为块级元素或内联元素。
块级元素在浏览器显示时,通常会以新行来开始(和结束)。
实例:
,
,
-
,
内联元素在显示时通常不会以新行开始。
实例: ,, ,
标签自带上下边距,消除边距方法:
CSS 的 Float(浮动),会使元素向左或向右移动,其周围的元素也会重新排列。
1.table布局
<!DOCTYPE html>
<html>
<head> </head>
<body>
<table style="width:500px;">
<tr>
<td colspan="2" style="background-color:blue;"><h1 style="margin:0;">主要的网页标题</h1></td>
</tr>
<tr>
<td style="background-color:red;width:100px;height:200px;vertical-align:top" >
<b>菜单</b><br/>//table布局与html布局有点不一样,table布局这里的元素是上下居中的,所以要想上对齐需要vertical-align:top
HTML<br/>
CSS<br/>
JavaScript<br/>
</td>
<td style="width:400;background-color:grey;vertical-align:top">内容在这里</td>
</tr>
<tr>
<td colspan="2" style="background-color:green;text-align:center;">版权 © runoob.com</td>
</tr>
</table>
</body>
</html>
2.div布局
<!DOCTYPE html>
<html>
<head> </head>
<body>
<div style="width:500px;">
<div style="background-color:blue;"><h1 style="margin:0;">主要的网页标题</h1></div>
<div style="background-color:red;width:100px;height:200px;float:left;">
<b>菜单</b><br/>
HTML<br/>
CSS<br/>
JavaScript<br/>
</div>
<div style="background-color:grey;width:400px;height:200px;float:left;">
内容在这里
</div>
<div style="background-color:green;text-align:center;clear:both;">版权 © runoob.com</div>//clear:both清除左右浮动影响
</div>
</body>
</html>
before 20050302