本类访问:this、父类访问:base
特性:
特性的使用方法很简单,只需要写在方法,类,枚举,字段等程序体的上面用[]
括起来即可,如下。
[Route("api/[controller]/[action]")]
[ApiController]
public class TestController:ControllerBase
{
[HttpGet]
[Obsolete]
public void Test()
{
Console.WriteLine("这是一个过时的方法");
}
}
常用特性:Obsolete特性、Conditional特性、DebuggerStepThrough特性、Serializable 特性
还有很多
属性:
private int hp;
public int Hp
{
get
{
return hp;
}
set
{
hp=value;
}
}
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerID { get; set; }
委托:
把方法当作参数在另一个方法中传递或调用
1.以delegate关键字开头。
2.返回类型+委托类型名+参数列表
delegate void MyDel(int a)
MyDel nc1 = new MyDel(AddNum);
namespace Func
{
public delegate void MyDel();//声明一个自定义委托
class Program
{
static void Main(string[] args)
{
MyDel say1 = SayHi;
MyDel say2 = new MyDel(SayHi);
say1();
say2();
}
static void SayHi()
{
Console.WriteLine("hi");
}
}
namespace Func
{
public delegate int MyDel(int num);//声明一个自定义委托
class Program
{
static int Add1(int a)
{
int b = 10 + a;
Console.WriteLine("——Add1———");
return b;
}
static int Add2(int a)
{
int b = 10 - a;
Console.WriteLine("——Add2———");
return b;
}
static void Calculate(MyDel ex, int a)
{
var result = ex(a);
Console.WriteLine(result + "\n");
}
static void Main(string[] args)
{
Calculate(Add1, 1);
Calculate(Add2, 10);
Console.ReadKey();
}
}
多播委托:
可以使用+=运算符,为委托新增方法。
同样可以使用-=运算符,为委托移除方法。
当委托列表中有几个方法时,调用委托时,则会依次经过各个方法,并返回列表最后一项方法的结果。
namespace Func
{
public delegate int MyDel(int num);//声明一个自定义委托
class Program
{
static int Add1(int a)
{
int b = 10 + a;
Console.WriteLine("——Add1———");
return b;
}
static int Add2(int a)
{
int b = 10 - a;
Console.WriteLine("——Add2———");
return b;
}
static void Calculate(MyDel ex, int a)
{
var result = ex(a);
Console.WriteLine(result + "\n");
}
static void Main(string[] args)
{
//Calculate(Add1, 1);
//Calculate(Add2, 10);
MyDel myDel = Add1;
myDel += Add2;
Calculate(myDel, 10);
Console.ReadKey();
}
}
事件:订阅、触发
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 事件学习
{
//定义一个领导类,发布事件
public class leader
{
//声明一个委托
public delegate void WorkHandle(string msg);
//实用自定义委托类型定义事件
public event WorkHandle workEvent;
//发出事件
public void goBackToWork(string msg)
{
//判断是否绑定了注册事件的方法
if (workEvent != null)
{
//事件触发
workEvent(msg);
}
}
}
//定义一个员工类处理事件
public class worker
{
//字段
public string Name;
//构造函数
public worker(string name)
{
Name = name;
}
//事件处理函数
public void sendMsg(string message)
{
Console.WriteLine(message);
Console.WriteLine(this.Name + ":知道了,我会去加班的!");
}
}
class Program
{
static void Main(string[] args)
{
//初始化领导对象
leader hu = new leader();
//实例化员工对象
worker xie = new worker("谢峰");
//订阅事件
//胡总.发布的事件+=领导.委托(谢峰.做事)
hu.workEvent += new leader.WorkHandle(xie.sendMsg);
//触发事件
hu.goBackToWork("胡:谢峰,快滚回去加班写代码!");
Console.WriteLine("_______________________________");
Console.ReadKey();
}
}
}
lamda表达式: (input parameters) => { statement; }
delegate int myDel(int x,int y); //声明委托
class Program
{
static void Main(string[] args)
{
myDel del = (x,y) => x+y; //返回x+y的结果
Console.WriteLine("values {0}",del(5,8)); //输出13
Console.ReadKey();
}
}
delegate int myDel(string str);
class Program
{
static void Main(string[] args)
{
myDel del = (str) =>
{
Console.WriteLine("hello {0}",str);
return 123;
};
Console.WriteLine("values {0}",del("world"));
Console.ReadKey();
}
}
匿名方法
using System;
delegate void NumberChanger(int n);
namespace DelegateAppl
{
class TestDelegate
{
static int num = 10;
public static void AddNum(int p)
{
num += p;
Console.WriteLine("Named Method: {0}", num);
}
public static void MultNum(int q)
{
num *= q;
Console.WriteLine("Named Method: {0}", num);
}
static void Main(string[] args)
{
// 使用匿名方法创建委托实例
NumberChanger nc = delegate(int x)
{
Console.WriteLine("Anonymous Method: {0}", x);
};
// 使用匿名方法调用委托
nc(10);
// 使用命名方法实例化委托
nc = new NumberChanger(AddNum);
// 使用命名方法调用委托
nc(5);
// 使用另一个命名方法实例化委托
nc = new NumberChanger(MultNum);
// 使用命名方法调用委托
nc(2);
Console.ReadKey();
}
}
}
反射:
泛型:
泛型是作用在编译期间的一种机制,即运行期间没有泛型的概念
泛型类:
using System;
using System.Collections.Generic;
namespace GenericApplication
{
public class MyGenericArray<T>
{
private T[] array;
public MyGenericArray(int size)
{
array = new T[size + 1];
}
public T getItem(int index)
{
return array[index];
}
public void setItem(int index, T value)
{
array[index] = value;
}
}
class Tester
{
static void Main(string[] args)
{
// 声明一个整型数组
MyGenericArray<int> intArray = new MyGenericArray<int>(5);
// 设置值
for (int c = 0; c < 5; c++)
{
intArray.setItem(c, c*5);
}
// 获取值
for (int c = 0; c < 5; c++)
{
Console.Write(intArray.getItem(c) + " ");
}
Console.WriteLine();
// 声明一个字符数组
MyGenericArray<char> charArray = new MyGenericArray<char>(5);
// 设置值
for (int c = 0; c < 5; c++)
{
charArray.setItem(c, (char)(c+97));
}
// 获取值
for (int c = 0; c < 5; c++)
{
Console.Write(charArray.getItem(c) + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
泛型接口:
interface IUSB<T,M>
{
T usbType { get; set; }
T ReadFile(T content);
M WriteFile(M content);
}
/实现接⼝后⾯可以不输⼊具体类型,⽤类的泛型传递
class Computer<T> : IUSB<T, float>
//继承的类后⾯可以不输⼊具体类型,⽤类的泛型传递
class MiniComputer<T> : Computer<T>
泛型方法:在泛型方法中,返回类型和/或参数类型由泛型类型参数来确
using System;
using System.Collections.Generic;
namespace GenericMethodAppl
{
class Program
{
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
static void Main(string[] args)
{
int a, b;
char c, d;
a = 10;
b = 20;
c = 'I';
d = 'V';
// 在交换之前显示值
Console.WriteLine("Int values before calling swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Char values before calling swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
// 调用 swap
Swap<int>(ref a, ref b);
Swap<char>(ref c, ref d);
// 在交换之后显示值
Console.WriteLine("Int values after calling swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Char values after calling swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
Console.ReadKey();
}
}
}
泛型委托:
using System;
using System.Collections.Generic;
delegate T NumberChanger<T>(T n);
namespace GenericDelegateAppl
{
class TestDelegate
{
static int num = 10;
public static int AddNum(int p)
{
num += p;
return num;
}
public static int MultNum(int q)
{
num *= q;
return num;
}
public static int getNum()
{
return num;
}
static void Main(string[] args)
{
// 创建委托实例
NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
// 使用委托对象调用方法
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
泛型重载:
class Person
{
}
class Person<T,U>
{
T name;
U age;
}
泛型约束:
如果泛型类需要调用泛型类型中的方法,就必须添加 约束。
public class AnimalManager<TAnimal> where TAnimal:Animal // 注意这里使用了泛型约束
{
public readonly List<TAnimal> animalList = new List<TAnimal>();
public void AddAnimal(TAnimal obj)
{
animalList.Add(obj);
}
public void Run()
{
foreach (TAnimal animal in animalList)
{
animal.Run(); // 这里现在就可以正常的访问了
}
}
常见数据结构:
数组(Array):在内存上连续分配的,而且元素类型是一样的,长度不变
string[] strs = new string[5];
strs[0] = "a";//赋值
strs[1] = "b";//赋值
strs[2] = "c";//赋值
strs[3] = "d";//赋值
strs[4] = "e";//赋值
strs[0] = "f";//修改
动态数组(ArrayList):在内存上连续分配的;元素没有类型限制,任何元素都是当成object处理,如果是值类型,会有装箱操作,不定长的 。若要使用则必须引入System.Collections
ArrayList arrayList = new ArrayList();
arrayList.Add("a");//增加
arrayList[0] = "b";//改
arrayList.Remove("a");//删除
列表(List<T>):内存上都是连续摆放;不定长;泛型,保证类型安全,避免装箱拆箱,融入了Array快速访问的优点以及ArrayList长度可变的优点,若要使用则必须引入System.Collections.Generic;
List<string> mList = new List<string>();
哈希表 (Hashtable<K,T>):K,T可为Object,有装箱拆箱,若要使用则必须引入System.Collections; 多线程读取
//查找数据一次到位 增删一次到位
//如果不同的key对应相同的地址,第二个在前面地址上+1 浪费空间,数据太多,重复定位 效率就下降
Hashtable hashtable = new Hashtable();
hashtable.Add("1","a");
hashtable[2] = "a";
hashtable["aaa"] = "a";
foreach (DictionaryEntry item in hashtable)
{
Debug.Log(" hashtable:" + item.Key.ToString()+"==" + item.Value .ToString());
}
Hashtable.Synchronized(hashtable );//线程安全 只有一个线程写 多个线程读
字典(Dictionary<K,T> ):单线程读取,若要使用则必须引入System.Collections.Generic;
Dictionary<int, string> dic = new Dictionary<int, string>();
dic.Add(1, "a");
dic.Add(2, "b");
dic.Add(3, "c");
dic.Add(4, "d");
foreach (var item in dic)
{
Debug.Log("Dictionary:" + item.Key.ToString() + "==" + item.Value.ToString());
}
链表(双向链表):元素不连续分配,泛型,每个元素都有记录前后节点;节点值可以重复;不能下标访问,找元素就只能遍历,查找慢;增删快。若要使用则必须引入System.Collections.Generic;
LinkedList<int> linkedList = new LinkedList<int>();
linkedList.AddFirst(111);//添加为第一个节点元素
linkedList.AddLast (555);//添加为最后一个节点元素
if (linkedList.Contains(111))
{
LinkedListNode<int> node = linkedList.Find(111);
linkedList.AddBefore(node, 222);//在指定节点前新增元素
linkedList.AddAfter(node, 222);在指定节点后新增元素
linkedList.Remove(node);//删除
}
linkedList.Remove(555);//删除
linkedList.RemoveFirst();//删除
linkedList.RemoveLast();//删除
单向链表:
环形链表:
堆栈:属于链表,先进后出
Stack<string> Stackstrs = new Stack<string>();
Stackstrs.Push("a");
Stackstrs.Push("b");
Stackstrs.Push("c");
Stackstrs.Push("d");
foreach (var item in Stackstrs)
{
Debug.Log("Stack:" + item.ToString());
}
队列:属于链表,先进先出
Queue<string> Queuestrs = new Queue<string>();
Queuestrs.Enqueue("a");
Queuestrs.Enqueue("b");
Queuestrs.Enqueue("c");
Queuestrs.Enqueue("d");
foreach (var item in Queuestrs)
{
Debug.Log("Queue:" + item.ToString());
}
相互转换:
//转换方法
byte[] bytes=new byte[5];
string str = System.Text.Encoding.UTF8.GetString(bytes);
byte[] decBytes = System.Text.Encoding.UTF8.GetBytes(str);
//Queue =>Array
Queue<string> Queuestrs1 = new Queue<string>();
string[] strs1 = Queuestrs1.ToArray();
//Array=>Queue
string[] strs2 = new string[3];
Queue<string> Queuestrs2 = new Queue<string>(strs2);
//Stack =>Array
Stack<string> Stackstrs1 = new Stack<string>();
string[] strs3 = Stackstrs1.ToArray();
//Array=>Queue
string[] strs4 = new string[3];
Stack<string> Stackstrs2 = new Stack<string>(strs4);
//Array=>List
string[] strs5 = new string[3];
List <string> Liststrs1 = new List<string>(strs5);
//List=>Array
Liststrs1.ToArray();