适合有java基础,快速转C#语言
目录
3.8.2. StreamReader 和 StreamWrite
1.1. Class对象结构与规则
this:代表当前这个类的对象
类是不占内存的,而对象是占内存的
① 对象变量名喜欢用:开头下划线+驼峰的命名方法 “_name”; 可能为了兼容它那丑陋的getset写法
② getset写法不同:直接访问obj._name不会调用get方法则返回原值,obj.Name会调用get方法
private string _name;
public string Name(){
get{return _name;}
set{_name = value;}
};
可缩写:public string Name(){get;set};
③ 属性变量的本质是俩个方法,一个是get 一个是set.....
1.2. 编译生成exe程序
顶部菜单栏/生成/生成解决方案 有俩个功效:1、帮忙检查是否存在语法错误;2、编译生成exe程序导出(项目右键/在文件资源管理器中打开文件夹/(项目文件夹/bin/debug/xx.exe))
>> 附加说明,通过打包出来的exe也可以反编译看自己写的源码;需要借助.net Reflector工具,双击打开后,把exe文件拖到其中打开即可查看对应项目中的各个对象
IL&Bytes:中间语言
1.3.构造函数与重载
① 对象基本创建在 命名空间和 主项目类中间的区域
public namespace CreateObjProject {
public class Student {
//构造函数
public Student(string name, int age, char gender){
this.Name = name;
this.Age = age;
this.Gender = gender;//相当于调用了set方法存储;没调用set的写法:this._gender = gender;
}
//重载:方法重载,入参个数不同,方法名相同
public Student(string name, int age, char gender, int chinese, int math){
this.Name = name; this.Age = age;
this.Gender = gender;this.Chinese = chinese;
this.Math = math;
}
}
}
② 和JAVA相同,当自定义了新的构造参数后,默认无参的构造参数都会失效
③构造函数互相调用function:this()
java中直接构造方法内第一行调用this(xxx);方法块是this(xx)之后调用,自定义内容之前调用
而C#中写法:
public Student(string name, int age, char gender){
this.Name = name;
this.Age = age;
this.Gender = gender;
}
public Student(string name):this(name,0,'w'){
//直接专向调用了Student(string name, int age, char gender)
}
1.4. struct 结构对象的用法
① 类似model层的写法,但是不需要new出来即可直接对对象赋值
② 当堆栈的空间很有限,且有大量的逻辑对象时,创建类要比创建结构好一些;
③ 在表现抽象和多级别的对象层次时,类是最好的选择,因为结构不支持继承
④ struct属于值类型,赋值等于深克隆;对象1修改属性对对象2无影响
public struct AddressBook { //字段、属性、方法、事件 }
public class Program { static void Main(string[] args) { PersonStruct p1, p2; //与类一样,但可以不new p1.Name = "张飞"; p1.MobilePhone = "13553663108"; p1.Birthday = DateTime.Now.AddYears(-10); p2 = p1; //将p1的值赋给p2 //由于是值类型,因此赋值等于将全部值全部复制到p2的栈空间 p2.Name = "关羽"; //然后修改p2的值看是否会影响p1 Console.WriteLine(p1.Name); //输出 张飞 没影响
}
}
⑤貌似比较喜欢往getset中写业务逻辑。。。
private int _distance;//距离
private double _price;//价格还是根据距离字段算出
public double Price {
get{
if(_distance > 0 && _distance <= 100){
return _distance * 1.0;//默认小数也是double类型
} else if(_distance >= 101 && _distance < 200 ){
return _distance * 0.95;
} else {
return _distance * 0.8;
}
}
}
public void ShowTicket(){
Console.WriteLine("{0}公里需要{1}元", Distance, Price);
}
1.5.析构函数
①当程序结束的时候,析构函数才执行
② 帮助我们释放资源
③ GC Garbage Collection 垃圾回收器自动回收
有可能程序结束时,GC没有马上释放资源(可能内存占用率还不高,垃圾不多);如果想资源马上被回收,需要在析构函数中定义回收资源垃圾
namespace _面向对象{
public class Student{
~Student(){ //和构造方法类似的写法
Console.WriteLine("My name is 细狗函数");
}
}
}
1.6. 命名空间
①快捷方式:提示需要引用内容,atl+shift+F10
②引用兄弟项目的命名空间:当前项目下/引用/添加引用/解决方案/项目(勾选即可);然后当前项目类中使用using 兄弟命名空间;就可以只用兄弟命名空间下的类
1.7.值类型和引用类型
1)值类型和引用类型在内存中存储的地方不同
2)在传递值类型和传递引用类型的时候,传递的方式不一样
值类型我们称之为值传递;引用类型称之为引用传递
值类型:int、double、bool、char、decimal、struct、enum
引用类型:string 、自定义类、数组
存储位置:
值类型的值存储在内存的栈中;
引用类型的值存储在内存的堆中;
1.8. 字符串string
1.8.1. 字符串的不可变性
堆中旧值不会被覆盖,而是开辟一块新的空间存新值
string s1 = "张三"; s1 = "孙权";
这个时候就等GC来销毁它,发现这个数据未被指向,马上就会销毁
1.8.2. 字符串不可修改(只读)
△ 怎么操作才能修改string的内容呢?
字符串 => char[] = s.TOCharArray(); => 修改对应下标的数据后 => 转回字符串new String(char[]);
1.8.3.StringBuilder
① 需要对字符串进行大量累加时,使用StringBuilder可以提高效率(不会每次都去创建堆空间),耗时非常少0.0422166s,而用string str += i;非常慢,20s都没出来结果(10w数据for)
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new stringBuilder();I
string str = null;//创建了一个计时器,用来记录程序运行的时间//00:00:00.0422166
Stopwatchsw=new Stopwatch();sw.start();//开始计时
for(int i = 0; i<100000; i++)
//str += i;sb.Append(i);
}
sw.stop();//结束计时Console.WriteLine(sb.Tostring());
Console.WriteLine(sw.Elapsed);
Console.ReadKey();
}
}
一切类型都可以调用.ToString方法转换成字符串类型
string内部方法:
>> 字符串提供的各种方法
1)、Length:获得当前字符串中字符的个数
2)、Toupper():将字符转换成大写形式
3)、ToLower():将字符串转换成小写形式
4)、Equals(string,Stringcomparison.ordinalIgnorecase):比较两个字符串,第二个参数:忽略大小写(策略模式)
5)、Split(new char[]{'-'},StringSplitOptions.RemoveEmptyEntries);//按照某字符分割,删除空白项
6)、字符串替换:string Replace(string oldValue, string newValue)将字符串中的出现oldValue的地方替换为newValue。例子:名字替换
7)、取子字符串:string Substring(int starindex),取从位置startIndex开始一直到最后的字符串;
8)、string Substring(int startIndex, int length),取从位置startIndex开始一直到最后的子字符串;(包含index项,需要+1)
9)、bool Contains(string value)判断字符串中是否含有子串 value
10)、bool StartsWithlstring value)判断字符串是否以子串value开始;
11)、bool EndsWth(string value)判断字符串是否以子串value结束;
12)、int IndexOf(string value):取子串value第一次出现的位置。
13)、LastIndexof:取子串value最后出现的位置。
14)、Trim():去除前后空格
15)、TrimEnd():去除后空格
16)、TrimStrat():去除前空格
17)、IsNullOrEmpty():是否为空或null判断
18)、Join(分隔符,params string[] arg);//将数组中每个元素用字符串的方式连起来
19)、Int lndexOf(string value,int startlndex):取出从某下标开始(包含开始下标),子串value第一次出现的位置。
1.8.2.File用法
系统自带文件操作类,支持指定读文件的编码类型;读写方法都已经帮你封装好了
string path = @"C:\Users\SpringRain\Desktop\1.txt";
string[] contents =File.ReadAllLines(path,Encoding.Default);
1.9. 继承
〇 所有类都直接或间接的继承于object类
① 子类继承父类的属性和方法,没继承父类的私有字段
② 一个子类只能有一个父类
③ 子类并没有继承父类的构造方法,但是子类会默认的调用父类无参数的构造方法
④ 调用父类有参的构造函数,用:base() 而java中是super();
public Student(string name, int age, char gender)
:base(name, age, gender){ //子类指定调用父类有参的构造函数
this.Name = name;
this.Age = age;
this.Gender = gender;
}
public class Person {//父类:基类
private int _id;
public int Id{get;set;}
}
public class Driver:Person { //子类也叫派生类
private string _name;
public string Name {
get{return this._name;}
set{ return _name = value;}
}
}
⑤ 类图可以查看类的继承关系
⑥ 子类重写父类的方法,+new
public new void SayHello(){ //重写父类的方法,需要加new修饰。。。
Console.WriteLine("大家好");
}
new 关键字的作用:
1、创建对象