学习资料:C#入门经典(第七版)
学习计划:一天至少一章,主要是熟悉语法以及背后的原理
编译环境IDE:VSC (Visual Stduio Community)
PS:老忘记的事情
- 类里面要写清楚数据是可访问类型是哪种
- foreach一个list,取出来的是object类型,要强制转换成对应派生类
第二章 编写C#程序
- Console.ReadKey():等待一个响应,即任意敲击键盘一次
- 右侧解决方案中,program.cs文件双击某个函数,可以跳转到对应的位置,起到了目录跳转的作用
第三章 变量和表达式
- 输出某种类型的最大值, type.MaxValue
- 输出多个变量Console.WriteLine($"{a},{b}"); Console.WriteLine("{0},{1}",a,b);这两个区别在于$和括号内容。0base
- 变量命名必须以 _ 字母 @开头
- @+string,可以让string里不再用转移字符
- 一元运算符'+'并不能把负数变正。是个比较奇怪的运算符,作用不明
- console是个静态类,不能被初始化
第四章 流程控制
- switch每一个case必须得break,这是和C++不同的地方
第五章 变量的更多内容
- 枚举的用法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { enum temp : int { a=1, b=2 } class Program { static void Main(string[] args) { temp tt = temp.a; int t = (int)temp.a; Console.WriteLine("{0} {1}",tt,t); } } }
- string.Trim(),可以从头开始去掉一些想删除的字符,从后开始删除一些想要删除的字符,直到没有或者当前字符不是被删字符数组的内容。string.TrimStart(), string.TrimEnd()字面意思理解一下。
- string.PadLeft(len,char),左边补空格到指定长度。当然还有PadRight(len)
- string.split(char[] or string []) both are ok,按照char[]中的字符或者string[]中的字符串来分割给定字符串
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { class Program { static void Main(string[] args) { string s = Console.ReadLine(); string[] word; string[] c = new string[2] { "aa", "dd" }; word = s.Split(c,System.StringSplitOptions.RemoveEmptyEntries); foreach (string t in word) Console.WriteLine(t); } } }
-
string.replace(char a,char b) 用b代替a
- var相当于C++中的auto
第六章 函数
- 函数用static
- 当使用params的时候,由于这是一个静态方法。当要定可变参数个数的时候,static int cul(params int[] a)
- 对于静态方法还得研究一下,这个问题和第二个问题有关。
- solve it ! 我们用的类class program其实是未定义的,但static是已经好了的可以直接用。要么我们新new program要么就定static
- C#中的引用,包括ref和out两种,形式基本相同。但,ref要求有初值,out在到目标函数的时候会丢失数据
- console.writeline和todouble可以通过引入头文件来解决。
- type.tryparse(string,out name) 检查string是否type类型,若是则赋值给name,返回真;否则返回假
- 委托不是很懂,等后面看到事件应该会明白些。暂时写了个readline的委托,writeline没写出来
第八章 面向对象编程
- OOP面向对象编程,UML统一建模语言
- C#一切皆对象,其中用 实例对象.方法/属性,方法和属性用()区别
- 静态构造函数用于初始化类中的静态成员,在创建实例化对象和访问该静态成员时会被默认调用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Console; using System.Diagnostics; using static System.Convert; namespace ConsoleApp1 { class Program { public class A { public int a; static int b; static A() { WriteLine("static"); b = 2; } public A() { WriteLine("default"); a = 1; } } static void Main(string[] args) { A temp=new A(); } } }
- 静态类只包含静态成员(属性和方法),并且每个成员都要指定共有还是私有,除了被static修饰的
- 接口最好不要随便改动,因为这是一个公共构建。如果需要改动,可以将接口扩展(创建一个新接口)。每个类继承一个接口后,可以避免写很多具有相同方法的类对象重载,有利于维护。接口有多态性,可以针对不同的类的相同方法。(BLOG)——面向接口编程
using System; using static System.Object; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Console; using System.Diagnostics; using static System.Convert; namespace ConsoleApp1 { class Program { public interface IMy_interface { void show(); } public class A : IMy_interface { public void show() { WriteLine("haha"); } } static void Main(string[] args) { IMy_interface temp = new A(); temp.show(); } } }
- System.object 是有所类的基类,万物皆对象。。!
第九章 定义类
- 构造函数可以给父类传递参数,也可以指定当前类要转移到当前的哪个构造函数
- 类的赋值是引用
- 有浅拷贝和深拷贝,和C++一样 (未完成)
第十章 定义类成员
- 公有变量用PscalCasing命名,帕斯卡拼写法。私有变量用camelCsing,骆驼拼写法。是两种命名规范
- readonly代表该变量只能在构造函数中赋值
- 静态成员只能通过 类名.成员 来调用
- override,代表方法重写
- set和get访问器key可以对赋值的内容进行封装(设立条件才能赋值,否则返回)。这样使用者就看不到内部的代码
- 两种写法,一种定义一个新的属性。或者直接public int x{set;get;}编译器会自动生成一个新的属性
- 当函数重写(虚函数)想调用基类的某个函数,那么用base.函数名()。this.就用当前实例的某个成员,能看得更加清晰
第十一章 集合、比较和转换
- 集合
- 建立动态长度集合
- 自定义集合(存在问题)
using System; using static System.Object; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace ConsoleApp1 { class Program { public class Animal { public string Name; public Animal (string s) { Name = s; } } public class Animals : CollectionBase { public void Add(Animal a) { List.Add(a); } public void Remove(Animal a) { List.Remove(a); } public Animals() { } } static void Main(string[] args) { Animals temp = new Animals(); temp.Add(new Animal("123")); temp.Add(new Animal("456")); foreach (Animal ani in temp) Console.WriteLine(ani.Name); //不知道为什么foreach中Animal写var会报错 } } }
-
定义索引符,有点像重载函数。
using System; using static System.Object; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace ConsoleApp1 { class Program { public class Animal { public string Name; public Animal (string s) { Name = s; } } public class Animals : CollectionBase { public void Add(Animal a) { List.Add(a); } public void Remove(Animal a) { List.Remove(a); } public Animal this[int index] { get { return (Animal)List[index]; } set { List[index] = value; } } } static void Main(string[] args) { Animals temp = new Animals(); temp.Add(new Animal("123")); temp.Add(new Animal("456")); Console.WriteLine(temp[1].Name); } } }
-
使用字典
-
自定义字典
using System; using static System.Object; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace ConsoleApp1 { class Program { public class Animal { public string Name; public Animal (string s) { Name = s; } } public class Animals : DictionaryBase { public void Add(Animal a,int v) { Dictionary.Add(a,v); } public void Remove(Animal a) { Dictionary.Remove(a); } public Animal this[Animal a] { get { return (Animal)Dictionary[a]; } set { Dictionary[a] = value; } } } static void Main(string[] args) { Animals temp = new Animals(); temp.Add(new Animal("123"),456); temp.Add(new Animal("222"), 333); foreach (DictionaryEntry t in temp) Console.WriteLine((t.Value)); } } }
-
实现一个迭代器,每次用yield return value 来返回值,使用接口IEnumerable。foreach每次的变量是value
-
迭代器遍历字典(未完成)
using System; using static System.Object; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace ConsoleApp1 { class Program { public class Animal { public string Name; public Animal (string s) { Name = s; } } public class Animals : DictionaryBase { public void Add(Animal a, Animal v) { Dictionary.Add(a,v); } public void Remove(Animal a) { Dictionary.Remove(a); } public Animal this[Animal a] { get { return (Animal)Dictionary[a]; } set { Dictionary[a] = value; } } public IEnumerable GetEnumerable() { foreach(object MyAnimal in Dictionary.Values) { yield return (Animal)MyAnimal; } } } static void Main(string[] args) { Animals temp = new Animals(); temp.Add(new Animal("123"),new Animal("456")); temp.Add(new Animal("222"), new Animal("333")); foreach (Animal MyAnimal in temp) Console.WriteLine(MyAnimal.Name); } } }
-
深复制(继承接口ICloneable)和浅复制(MemberwiseClone())
-
比较
-
拆箱和装:装箱和拆箱实质上是引用类型和值类型的转换
-
is运算符。A是B的派生类,A继承接口B,A可以拆箱到B
- 重载+运算符
-
using System;
using static System.Object;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace ConsoleApp1
{
class Program
{
class A
{
public int val;
public A(int v)
{
val = v;
}
public static A operator+(A temp1,A temp2)
{
A NewTemp = new A(0);
NewTemp.val= temp1.val + temp2.val;
return NewTemp;
}
}
static void Main(string[] args)
{
A t1 = new A(1);
A t2 = new A(2);
t1 = t1 + t2;
Console.WriteLine(t1.val);
}
}
}
- 类内实现IComparable,类外实现IComparer,后者有点像自定义CMP,前者像类内重载。
- 利用IComparable实现集合排序
using System; using static System.Object; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace ConsoleApp1 { class Program { public class A : IComparable { public int val; public A(int v) { val = v; } public int CompareTo(object obj) { if(this.val >= ((A)obj).val) { return 1; } else { return 0; } } } static void Main(string[] args) { ArrayList list = new ArrayList(); list.Add(new A(3)); list.Add(new A(4)); list.Add(new A(3)); list.Sort(); for (int i = 0; i < list.Count; i++) Console.WriteLine((list[i] as A).val); } } }
- 利用IComparer实现集合排序
-
using System; using static System.Object; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace ConsoleApp1 { class Program { public class A { public int val; public A(int v) { val = v; } } public class CMP : IComparer<A> { public int Compare(A t1,A t2) { if(t1.val>=t2.val) { return 1; } else { return 0; } } } static void Main(string[] args) { List<A> list = new List<A>(); list.Add(new A(3)); list.Add(new A(4)); list.Add(new A(3)); list.Sort(new CMP());//arraylist不允许这么用 for (int i = 0; i < list.Count; i++) Console.WriteLine(((A)list[i]).val); } } }
-
- 转换 a as T,将a变量转化为T类型的变量,如果不能隐式转换则为null
- 利用IComparable实现集合排序
第十二章 泛型
- 可空类型:int? a;
- a??b 等价a==null?b:a,和三目表达式一样
快捷键
Ctrl+shift+n | 新建项目 |
技巧
- 自己可以根据习惯,设定一些快捷键,设置注释和解除注释快捷键。个人是用惯了codeblock的快捷键,把注释设置为Ctrl+Shift+C,解除设置为Ctrl+Shift+X