using System;
using System.Collections;
namespace lesson4_Hashtable知识点练习题
{
class Monster
{
public Hashtable hashtable = new Hashtable();
public void Add(int id,string name)
{
Console.WriteLine("添加ID为{0}的{1}", id,name);
hashtable.Add(id, name);
foreach (object item in hashtable.Keys)
{
Console.WriteLine("现有怪物有ID为{0}的{1}", item,hashtable[item]);
}
Console.WriteLine();
}
public void Remove(int id)
{
if (hashtable.Contains(id))
{
Console.WriteLine("ID为{0}的{1}已移除", id, hashtable[id]);
hashtable.Remove(id);
}
else
{
Console.WriteLine("不存在ID为{0}的怪物", id);
}
foreach (object item in hashtable.Keys)
{
Console.WriteLine("现有怪物有ID为{0}的{1}", item, hashtable[item]);
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hashtable知识点练习题");
#region 练习题1
//请描述Hashtable的存储规则
//Hashtable(又称散列表)是基于键的哈希代码组织起来的 键/值对
//一个键值对形式存储的 容器
//一个键 对应一个值
//类型是object
#endregion
#region 练习题2
//制作一个怪物管理器,提供创建怪物,移除怪物的方法,每个怪物都有自己的唯一ID
Monster monster = new Monster();
monster.Add(1, "怪物1");
monster.Add(2, "怪物2");
monster.Remove(1);
#endregion
}
}
}
5.泛型
using System;
namespace lesson5_泛型
{
#region 泛型是什么
//泛型实现了类型参数化,达到代码重用目的
//通过类型参数化来实现同一份代码上操作多种类型
//泛型相当于类型占位符
//定义类或方法时使用替代符代表变量类型
//当真正使用类或者方法时再具体指定类型
#endregion
#region 泛型分类
//泛型类和泛型接口
//基本语法:
//class 类名<泛型占位字母>
//interface 接口名<泛型占位字母>
//泛型函数
//基本语法:函数名<泛型占位字母>(参数列表)
//注意:泛型占位字母可以有多个,用逗号分开
#endregion
#region 泛型类和接口
//泛型类
class TestClass
{
public T value;
}
class TestClass2
{
public T1 value1;
public T2 value2;
public K value3;
public M value4;
public LL value5;
public Key value6;
public Value value7;
}
//泛型接口
interface TestInterface
{
T value
{
get;
set;
}
}
class Test : TestInterface
{
public int value { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
}
#endregion
#region 泛型方法
//1.普通类中的泛型方法
class Test2
{
public void TestFun(T value)
{
Console.WriteLine(value);
}
public void TestFun()
{
//用泛型类型 再里面做一些逻辑处理
T t = default(T);
}
public T TestFun(string v)
{
return default(T);
}
public void TestFun(T t, K k, M m)
{
}
}
//2.泛型类中的泛型方法
class Test2
{
public T value;
public void TestFun(K k)
{
Console.WriteLine(k);
}
//这个不叫泛型方法 因为 T是泛型类申明的时候 就指定 在使用这个函数的时候
//我们不能再去动态的变化了
public void TestFun(T t)
{
}
}
#endregion
#region 泛型的作用
//1.不同类型对象的相同逻辑就可以选择泛型
//2.使用泛型可以一定程度避免装箱拆箱
//举例:优化ArrayList
class ArrayList
{
private T[] array;
public void Add(T value)
{
}
public void Remove(T value)
{
}
}
#endregion
#region 总结
//1.申明泛型时 它只是一个类型的占位符
//2.泛型真正起作用的时候 是在使用它的时候
//3.泛型占位字母可以有n个 用逗号隔开
//4.泛型占位字母一般是大写字母
//5.不确定泛型类型时 获取默认值 可以使用 default(占位字符)
//6.看到 <>包裹的字母 那肯定是泛型
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("泛型");
TestClass t = new TestClass();
t.value = 10;
Console.WriteLine(t.value);
TestClass t2 = new TestClass();
t2.value = "123123";
Console.WriteLine(t2.value);
TestClass2, uint, short> t3 = new TestClass2, uint, short>();
Test2 tt = new Test2();
tt.TestFun("123123");
Test2 tt2 = new Test2();
tt2.TestFun(10);
tt2.TestFun("123");
tt2.TestFun(1.2f);
}
}
}
泛型练习题
using System;
namespace lesson5_泛型练习题
{
#region 练习题1
//定义一个泛型方法,方法内判断该类型为何类型,并返回类型的名称与占有的字节数,
//如果是int,则返回"整形,4字节"
//只考虑以下类型
//int:整形
//char:字符
//float:单精度浮点数
//string:字符串
//如果是其他类型,则返回"其他类型"
//(可以通过typeof(类型)==typeof(类型))的方式进行类型判断
class Test
{
public void Fun(T t)
{
if (typeof(T) == typeof(int))
{
Console.WriteLine("{0},{1}字节", "整形", sizeof(int));
}
else if (typeof(T) == typeof(char))
{
Console.WriteLine("{0},{1}字节", "字符", sizeof(char));
}
else if (typeof(T) == typeof(float))
{
Console.WriteLine("{0},{1}字节", "单精度浮点数", sizeof(float));
}
//else if (typeof(T) == typeof(double))
//{
// Console.WriteLine("{0},{1}字节", "单精度浮点数", sizeof(double));
//}
else if (typeof(T) == typeof(string))
{
Console.WriteLine("{0},{1}字节", "字符串", "?");
}
else
{
Console.WriteLine("其它类型");
}
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("泛型练习题");
Test t = new Test();
t.Fun(1);
Test t1 = new Test();
t.Fun(1.2f);
//Test t2 = new Test();
//t.Fun(1.11);
}
}
}
6.泛型约束
using System;
namespace lesson6_泛型约束
{
#region 泛型知识回顾
class TestClass
{
public T t;
public U u;
//非泛型函数
public U TestFun(T t)
{
return default(U);
}
//泛型函数
public V TestFun(K k)
{
return default(V);
}
}
#endregion
#region 什么是泛型约束
//让泛型的类型有一定的限制
//关键字:where
//泛型约束一共有6种
//1.值类型 where 泛型字母:struct
//2.引用类型 where 泛型字母:class
//3.存在无参公共构造函数 where 泛型字母:new()
//4.某个类本身或者其派生类 where 泛型字母:类名
//5.某个接口的派生类型 where 泛型字母:接口名
//6.另一个泛型类型本身或者派生类型 where 泛型字母:另一个泛型字母
// where 泛型字母:(约束类型)
#endregion
#region 各泛型约束讲解
#region 值类型约束
class Test1 where T : struct
{
public T value;
public void TestFun(K k) where K : struct
{
}
}
#endregion
#region 引用类型约束
class Test2 where T : class
{
public T value;
public void TestFun(K k) where K : class
{
}
}
#endregion
#region 公共无参构造约束
class Test3 where T : new()
{
public T value;
public void TestFun(K k) where K : new()
{
}
}
class Test1
{
}
class Test2
{
public Test2(int a)
{
}
}
#endregion
#region 类约束
class Test4 where T : Test1
{
public T value;
public void TestFun(K k) where K : Test1
{
}
}
class Test3 : Test1
{
}
#endregion
#region 接口约束
interface IFly
{
}
class Test4 : IFly
{
}
class Test5 where T : IFly
{
public T value;
public void TestFun(K k) where K : IFly
{
}
}
#endregion
#region 另一个泛型约束
class Test6 where T : U
{
public T value;
public void TestFun(K k) where K : V
{
}
}
#endregion
#endregion
#region 约束的组合使用
//new()放在最后
class Test7 where T : class,new()
{
}
#endregion
#region 多个泛型有约束
class Test8 where T : class, new() where K : struct
{
}
#endregion
#region 总结
//泛型约束:让类型有一定限制
//class
//struct
//new()
//类名
//接口名
//另一个泛型字母
//注意:
//1.可以组合使用
//2.多个泛型约束 用 where 连接即可
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("泛型约束");
TestClass t = new TestClass();
t.t = "123123";
t.u = 10;
t.TestFun(1.4f);
//值类型约束
Test1 t1 = new Test1();
t1.TestFun(1.3f);
//引用类型约束
Test2 t2 = new Test2();
t2.value = new Random();
t2.TestFun
泛型约束练习题
using System;
namespace lesson6_泛型约束练习题
{
#region 练习题1
//用泛型实现一个单例模式基类
class SingleBase where T : new()
{
private static T instance = new T();
public static T Instance
{
get
{
return instance;
}
}
}
class GameMgr : SingleBase
{
public int value = 10;
}
class Test : SingleBase
{
public int value = 10;
}
class Test2
{
private static Test2 instance = new Test2();
public int value = 10;
private Test2()
{
}
public static Test2 Instance
{
get
{
return instance;
}
}
}
#endregion
#region 练习题2
//利用泛型知识点,仿造ArrayList实现一个不确定数组类型的类
//实现增删查改方法
class ArrayList
{
private T[] array;//创建泛型数组
private int count;//当前存储的数的数量
public ArrayList()
{
count = 0;
array = new T[16];
}
///
/// 获取容量
///
public int Capacity
{
get
{
return array.Length;
}
}
///
/// 得到具体存了几个值
///
public int Count
{
get
{
return count;
}
}
public void Add(T value)
{
if (count > Capacity)
{
//搬家 每次 家扩容2倍
T[] temp = new T[Capacity * 2];
for (int i = 0; i < Capacity; i++)
{
temp[i] = array[i];
}
//重新指向地址
array = temp;
}
//不需要扩容 直接加
array[count] = value;
++count;
}
public void Remove(T value)
{
//这个地方 不是小于数组的容量
//是小于 具体存了几个值
int index = -1;
for (int i = 0; i < Count; i++)
{
//不能用==去判断 因为 不是所有的类型都重载了运算符
if (array[i].Equals(value))
{
index = i;
break;
}
}
//只要不等于-1 就证明找到了 那就去移除
if (index != -1)
{
RemoveAt(index);
}
}
public void RemoveAt(int index)
{
//索引合法不
if (index < 0 || index >= Count)
{
Console.WriteLine("索引不合法");
return;
}
//后面的往前放
for (; index < Count - 1; index++)
{
array[index] = array[index + 1];
}
//把一个数移除了 后面的往前面放 那么最后一个 要移除
array[Count - 1] = default(T);
--count;
}
public T this[int index]
{
get
{
if (index < 0 || index >= Count)
{
Console.WriteLine("索引不合法");
return default(T);
}
return array[index];
}
set
{
if (index < 0 || index >= Count)
{
Console.WriteLine("索引不合法");
return;
}
array[index] = value;
}
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("泛型约束练习题");
}
}
}
7.常用泛型数据结构类_List
using System;
using System.Collections.Generic;
namespace lesson7_常用泛型数据结构类_List
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("常用泛型数据结构类_List");
#region List的本质
//List是一个C#为我们封装好的类
//它的本质是一个可变类型的泛型数组
//List类帮助我们实现了很多方法
//比如泛型数组的增删查改
#endregion
#region 申明
//需要引用命名空间
//using System.Collections.Generic
List list = new List();
List list2 = new List();
List list3 = new List();
#endregion
#region 增删查改
#region 增
//单个加
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
list2.Add("123");
//范围加
List listStr = new List();
listStr.Add("123");
list2.AddRange(listStr);
//插入
list.Insert(0, 999);
Console.WriteLine(list[0]);
#endregion
#region 删
//1.移除指定元素
list.Remove(1);
//2.移除指定位置的元素
list.RemoveAt(0);
//3.清空
list.Clear();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
#endregion
#region 查
//1.得到指定位置的元素
Console.WriteLine(list[0]);
//2.查看元素是否存在
if (list.Contains(1))
{
Console.WriteLine("存在元素1");
}
//3.正向查找元素位置
// 找到就返回位置 找不到 就返回-1
int index = list.IndexOf(5);
Console.WriteLine(index);
//4.反向查找元素位置
// 找到就返回位置 找不到 就返回-1
index = list.LastIndexOf(2);
Console.WriteLine(index);
#endregion
#region 改
Console.WriteLine(list[0]);
list[0] = 99;
Console.WriteLine(list[0]);
#endregion
#endregion
#region 遍历
//长度
Console.WriteLine(list.Count);
//容量
//避免产生垃圾
Console.WriteLine(list.Capacity);
for (int i = 0; i < list.Count; i++)
{
Console.Write(" " + list[i]);
}
Console.WriteLine();
foreach (int item in list)
{
Console.Write(" " + item);
}
#endregion
}
}
}
常用泛型数据结构类_List练习题
using System;
using System.Collections.Generic;
namespace lesson7_常用泛型数据结构类_List练习题
{
#region 练习题3
//一个Monster基类,Boss和Gablin类继承它。
//在怪物类的构造函数中,将其存储到一个怪物List中
//遍历列表可以让Boss和Gablin对象产生不同攻击
class Monster
{
public Monster()
{
}
public virtual void Atk()
{
}
}
class Boss:Monster
{
public override void Atk()
{
Console.WriteLine("Boss攻击");
}
}
class Gablin : Monster
{
public override void Atk()
{
Console.WriteLine("Gablin攻击");
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("常用泛型数据结构类_List练习题");
#region 练习题1
//请描述List和ArrayList的区别
//List内部封装的是一个泛型数组
//ArrayList内部封装的是一个object数组
#endregion
#region 练习题2
//建立一个整形List,为它添加10~1
//删除List中第五个元素
//遍历剩余元素并打印
List list = new List();
for (int i = 10; i > 0; i--)
{
list.Add(i);
}
list.RemoveAt(4);
foreach (int item in list)
{
Console.Write(item + " ");
}
Console.WriteLine();
#endregion
#region 练习题3
//一个Monster基类,Boss和Gablin类继承它。
//在怪物类的构造函数中,将其存储到一个怪物List中
//遍历列表可以让Boss和Gablin对象产生不同攻击
Boss b = new Boss();
Gablin g = new Gablin();
List monsters = new List();
monsters.Add(b);
monsters.Add(g);
for (int i = 0; i < monsters.Count; i++)
{
monsters[i].Atk();
}
#endregion
}
}
}
using System;
namespace lesson12_委托练习题
{
#region 练习题1
//一家三口,妈妈做饭,爸爸妈妈和孩子都要吃饭
//用委托模拟做饭——>开饭——>吃饭的过程
abstract class Person
{
public abstract void Eat();
}
class Mother : Person
{
public Action beginEat;
public override void Eat()
{
Console.WriteLine("妈妈吃饭");
}
public void DoFood()
{
Console.WriteLine("妈妈做饭");
Console.WriteLine("妈妈做饭做好了");
//执行委托函数
if (beginEat != null)
{
beginEat();
}
}
}
class Father : Person
{
public override void Eat()
{
Console.WriteLine("爸爸吃饭");
}
}
class Son : Person
{
public override void Eat()
{
Console.WriteLine("孩子吃饭");
}
}
#endregion
#region 练习题2
//怪物死亡后,玩家要加10块钱,界面要更新数据
//成就要累加怪物击杀数,请用委托来模拟实现这些功能
//只用写核心逻辑表现这个过程,不用写的太复杂
class Monster
{
public string name;
public Monster(string name)
{
this.name = name;
}
public void Dead(Monster monster)
{
if (monster.name != null)
{
Console.WriteLine("怪物{0}死亡!!!",monster.name);
monster.name = null;
}
else
{
Console.WriteLine("当前无更多怪物可击杀");
}
}
}
class Player
{
public Action action;
public string name;
public Player(string name)
{
this.name = name;
}
//击杀怪物数
public int kills;
//钱
public int money;
public void KillMonster(Monster monster)
{
if (monster.name != null)
{
kills++;
money += 10;
}
}
public void Show()
{
Console.Write("玩家{0}已达成击杀怪物{1}个",name,kills);
Console.WriteLine(" " + "玩家{0}已有{1}块钱",name,money);
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("委托练习题");
Mother m = new Mother();
Father f = new Father();
Son s = new Son();
m.beginEat += f.Eat;
m.beginEat += s.Eat;
m.beginEat += m.Eat;
//做饭
m.DoFood();
Monster monster1 = new Monster("1");
Monster monster2 = new Monster("2");
Monster monster3 = new Monster("3");
Monster monster4 = new Monster("4");
Monster monster5 = new Monster("5");
Player player1 = new Player("战士");
player1.action += player1.KillMonster;
player1.action += monster1.Dead;
player1.action(monster1);
player1.Show();
//怪物1死亡!!!
//玩家战士已达成击杀怪物1个 玩家战士已有10块钱
player1.action(monster2);
player1.Show();
//怪物2死亡!!!
//玩家战士已达成击杀怪物2个 玩家战士已有20块钱
player1.action(monster2);
player1.Show();
//当前无更多怪物可击杀
//玩家战士已达成击杀怪物2个 玩家战士已有20块钱
}
}
}
using System;
namespace lesson19_预处理器指令练习题
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("预处理器指令练习题");
#region 练习题1
//请说出至少4种预处理器指令
//#define 定义一个符号 (没有值的变量)
//#undef 取消定义一个符号
//#if
//#elif
//#else
//#endif
//#warning
//#error
#endregion
}
#region 练习题2
//请使用预处理器指令实现
//写一个函数计算两个数
//当是Unity5版本时算加法
//当是Unity2017版本时算乘法
//当时Unity2020版本时算减法
//都不是返回0
static int Calc(int a, int b)
{
#if Unity5
return a + b;
#elif Unity2017
return a * b;
#elif Unity2020
return a - b;
#else
return 0;
#endif
}
#endregion
}
}
20.反射
using System;
using System.Reflection;
using System.Threading;
namespace lesson20_反射
{
#region 知识回顾
//编译器是一种翻译程序
//它用于将源语言程序翻译为目标语言程序
//源语言程序:某种程序设计语言写成的,比如C#、C、C++、Java等语言写的程序
//目标语言程序:二进制数表示的伪机器代码写的程序
#endregion
#region 什么是程序集
//程序集是经由百年一起编译得到的,供进一步编译执行的那个中间产物
//在WINDOWS系统中,它一般表现为后缀.dll(库文件)或者是.exe(可执行文件)的格式
//说人话:
//程序集就是我们写的一个代码集合,我们现在写的所有代码
//最终都会被编译器翻译为一个程序集供别人使用
//比如一个代码库文件(dll)或者一个可执行文件(exe)
#endregion
#region 元数据
//元数据就是用来描述数据的数据
//这个概念不仅仅用于程序上,在别的领域也有元数据
//说人话:
//程序中的类,类中的函数、变量等等信息就是 程序的元数据
//有关程序以及类型的数据被称为 元数据,它们保存在程序集中
#endregion
#region 反射的概念
//程序在运行时,可以查看其他程序集或者自身的元数据
//一个运行的程序查看本身或者其它程序的元数据的行为就叫做反射
//说人话:
//在程序运行时。通过反射可以得到其它程序集或者自己程序集代码的各种信息
//类,函数,变量,对象等等,实例化它们,执行它们,操作它们
#endregion
#region 反射的作用
//因为反射可以在程序编译后获得信息,所以它提高了程序的拓展性和灵活性
//1.程序运行时得到所有元数据,包括元数据的特性
//2.程序运行时,实例化对象,操作对象
//3.程序运行时创建新对象,用这些对象执行任务
#endregion
class Test
{
private int i = 1;
public int j = 0;
public string str = "123";
public Test()
{
}
public Test(int i)
{
this.i = i;
}
public Test(int i, string str) : this(i)
{
this.str = str;
}
public void Speak()
{
Console.WriteLine(i);
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("反射");
#region 语法相关
#region Type
//Type(类的信息类)
//它是反射功能的基础!
//它是访问元数据的主要方式
//使用 Type 的成员获取有关类型申明的信息
//有关类型的成员(如构造函数,方法,字段,属性和类的事件)
#region 获取Type
//1.万物之父object中的 GetType()可以获取对象的Type
int a = 42;
Type type = a.GetType();
Console.WriteLine(type);
//2.通过typeof关键字 传入类名 也可以得到对象的Type
Type type2 = typeof(int);
Console.WriteLine(type2);
//3.通过类的名字 也可以获取类型
// 注意 类名必须包含命名空间 不然找不到
Type type3 = Type.GetType("System.Int32");
Console.WriteLine(type3);
#endregion
#region 得到类的程序集信息
//可以通过Type可以得到类型所在程序集信息
Console.WriteLine(type.Assembly);
Console.WriteLine(type2.Assembly);
Console.WriteLine(type3.Assembly);
#endregion
#region 获取类中的所有公共成员
//首先得到Type
Type t = typeof(Test);
//然后得到所有公共成员
//需要引用命名空间 using System.Reflection;
MemberInfo[] infos = t.GetMembers();
for (int i = 0; i < infos.Length; i++)
{
Console.WriteLine(infos[i]);
}
#endregion
#region 获取类的公共构造函数并调用
//1.获取所有构造函数
ConstructorInfo[] ctors = t.GetConstructors();
for (int i = 0; i < ctors.Length; i++)
{
Console.WriteLine(ctors[i]);
}
//2.获取其中一个构造函数 并执行
//得构造函数传入 Type数组 数组中内容按顺序是参数类型
//执行构造函数传入 object数组 表示按顺序传入的参数
// 2-1 得到无参构造
ConstructorInfo info = t.GetConstructor(new Type[0]);
//执行无参构造 无参构造 没有参数 传null
Test obj = info.Invoke(null) as Test;
Console.WriteLine(obj.j);
// 2-2 得到有参构造
ConstructorInfo info2 = t.GetConstructor(new Type[] { typeof(int) });
obj = info2.Invoke(new object[] { 2 }) as Test;
Console.WriteLine(obj.str);
ConstructorInfo info3 = t.GetConstructor(new Type[] { typeof(int), typeof(string) });
obj = info3.Invoke(new object[] { 4, "4444" }) as Test;
Console.WriteLine(obj.str);
#endregion
#region 获取类的公共成员变量
//1.得到所有成员变量
FieldInfo[] fieldInfos = t.GetFields();
for (int i = 0; i < fieldInfos.Length; i++)
{
Console.WriteLine(fieldInfos[i]);
}
//2.得到指定名称的公共成员变量
FieldInfo infoj = t.GetField("j");
Console.WriteLine(infoj);
//3.通过反射获取和设置对象的值
Test test = new Test();
test.j = 99;
test.str = "2222";
//3-1通过反射 获取对象的某个变量的值
Console.WriteLine(infoj.GetValue(test));
//3-2通过反射 设置指定对象的某个变量的值
infoj.SetValue(test, 100);
Console.WriteLine(infoj.GetValue(test));
#endregion
#region 获取类的公共成员方法
//通过Type类中的 GetMethod方法 得到类中的方法
//MethodInfo 是方法的反射信息
Type strType = typeof(string);
MethodInfo[] methods = strType.GetMethods();
for (int i = 0; i < methods.Length; i++)
{
Console.WriteLine(methods[i]);
}
//1.如果存在方法重载 用Type数组表示参数类型
MethodInfo subStr = strType.GetMethod("Substring",new Type[] { typeof(int),typeof(int)});
//2.调用该方法
//注意:如果是静态方法 Invoke中的第一个参数传null即可
string str = "Hello,World!";
object result=subStr.Invoke(str,new object[] {7,5});
Console.WriteLine(result);
#endregion
#region 其他
//Type
//得枚举
//GetEnumName
//GetEnumNames
//得事件
//GetEvent
//GetEvents
//得接口
//GetInterface
//GetInterfaces
//得属性
//GetProperty
//GetPropertys
//等等
#endregion
#endregion
#region Assembly
//程序集类
//主要用来加载其他程序集,加载后
//才能使用Type来使用其他程序集中的信息
//如果想要使用不是自己程序集中的内容 需要先加载程序集
//比如 dll文件(库文件)
//简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类
//三种加载程序集的函数
//一般用来加载在同一文件下的其它程序集
//Assembly asembly2 = Assembly.Load("程序集名称");
//一般用来加载不在同一文件下的其它程序集
//Assembly asembly = Assembly.LoadFrom("包含程序集清单的文件的名称或路径");
//Assembly asembly3 = Assembly.LoadFile("要加载的文件的完全限定路径");
//1.先加载一个指定程序集
Assembly assembly = Assembly.LoadFrom(@"D:\学习\C#\CSharp进阶\lesson18-多线程练习题\bin\Debug\netcoreapp3.1\lesson18-多线程练习题");
Type[] types = assembly.GetTypes();
for (int i = 0; i < types.Length; i++)
{
Console.WriteLine(types[i]);
}
//2.再加载程序集中的一个类对象 之后才能使用反射
Type icon = assembly.GetType("lesson18-多线程练习题.Icon");
MemberInfo[] members = icon.GetMembers();
for (int i = 0; i < members.Length; i++)
{
Console.WriteLine(members[i]);
}
//通过反射 实例化一个 icon对象
//首先得到枚举Type 来得到可以传入的参数
Type moveDir = assembly.GetType("lesson18-多线程练习题.E_MoveDir");
FieldInfo right = moveDir.GetField("Right");
//直接实例化对象
Object iconObj = Activator.CreateInstance(icon, 10, 5, right.GetValue(null));
//得到对象中的方法 通过反射
MethodInfo move = icon.GetMethod("Move");
MethodInfo draw = icon.GetMethod("Draw");
MethodInfo clear = icon.GetMethod("Clear");
Console.Clear();
while (true)
{
Thread.Sleep(1000);
clear.Invoke(iconObj, null);
draw.Invoke(iconObj, null);
move.Invoke(iconObj, null);
}
//3.类库工程创建
#endregion
#region Activator
//用于快速实例化对象的类
//用于将Type对象快捷实例化为对象
//先得到Type
//然后 快速实例化一个对象
Type testType = typeof(Test);
//1.无参构造
Test testObj = Activator.CreateInstance(testType) as Test;
Console.WriteLine(testObj.str);
//2.有参构造
testObj = Activator.CreateInstance(testType, 99) as Test;
Console.WriteLine(testObj.j);
testObj = Activator.CreateInstance(testType, 55, "111222") as Test;
Console.WriteLine(testObj.j);
#endregion
#endregion
}
}
//总结
//反射
//在程序运行时,通过反射可以得到其他程序集或者自己的程序集代码的各种信息
//类、函数、变量、对象等等,实例他们,执行他们,操作他们
//关键类
//Type
//Assembly
//Activator
//对于我们的意义
//在初中级阶段 基本不会使用反射
//所有目前对于大家来说,了解反射可以做申明就行
//很长时间都不会用到反射相关知识点
//为什么要学反射
//为了之后学习Unity引擎的基本工作原理做铺垫
//Unity引擎的基本工作机制 就是建立在反射的基础上
}
反射练习题
using System;
namespace lesson20_反射练习题
{
#region 练习题1
//新建一个类库工程
//有一个Player类,有姓名、血量、攻击力、防御力、位置等信息
//有一个无参构造函数
//再新建一个控制台工程
//通过反射的形式使用类库工程生成的dll程序集
//实例化一个Player对象
class Player
{
public string name;
public int hp;
public int atk;
public int def;
public int[,] position;
public Player()
{
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("反射练习题");
}
}
}
21.特性
#define Fun
using System;
using System.Runtime.CompilerServices;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace lesson21_特性
{
#region 特性是什么
//特性是一种允许我们向程序的程序集添加元数据的语言结构
//它是用于保存程序结构信息的某种特殊类型的类
//特性提供功能强大的方法以将申明信息与 C# 代码(类型、方法、属性等)相关联
//特性与程序实体关联后,即可在运行时使用反射查询特性信息
//特性的目的是告诉编译器把程序结构的某组元数据嵌入程序集中
//它可以放置在几乎所有的申明中(类、变量、函数等等申明)
//说人话:
//特性本质是个类
//我们可以利用特性类为元数据添加额外信息
//比如一个类、成员变量、成员方法等等为他们添加更多的额外信息
//之后可以通过反射来获取这些额外信息
#endregion
#region 自定义特性
//继承特性基类 Attribute
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field,AllowMultiple =true,Inherited =false)]
class MyCustomAttribute : Attribute
{
//特性中的成员 一般根据需求来写
public string info;
public MyCustomAttribute(string info)
{
this.info = info;
}
public void TestFun()
{
Console.WriteLine("特性的方法");
}
}
#endregion
#region 特性的使用
//基本语法
//[特性名(参数列表)]
//本质上 就是在调用特性类的构造函数
//写在哪里?
//类、函数、变量上一行,表示他们具有该特性信息
[MyCustom("自己写的用于计算的类")]
[MyCustom("自己写的用于计算的类")]
class MyClass
{
[MyCustom("这是一个成员变量")]
public int value;
//[MyCustom("这是一个用于计算加法的函数")]
//public void TestFun([MyCustom("函数参数")] int a)
//{
//}
public void TestFun(int a)
{
}
}
#endregion
#region 限制自定义特性的使用范围
//通过为特性类 加特性 限制其使用范围
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = true)]
//参数一:AttributeTargets 特性能够用在哪些地方
//参数二:AllowMultiple 是否允许多个特性实例用在同一个目标上
//参数三:Inherited 特性是否能被派生类和重写成员继承
public class MyCustom2Attribute : Attribute
{
}
#endregion
#region 系统自带特性——过时特性
//过时特性
//Obsolete
//用于提示用户 使用的方法等成员已经过时 建议使用新方法
//一般加载函数前的特性
class TestClass
{
//参数一:调用过时方法时 提示的内容
//参数二:true-使用该方法时会报错 false-使用该方法时直接警告
[Obsolete("OldSpeak方法已经过时了,请使用Speak方法",false)]
public void OldSpeak(string str)
{
Console.WriteLine(str);
}
public void Speak()
{
Console.WriteLine("123");
}
public void SpeakCaller(string str, [CallerFilePath]string fileName = "",
[CallerLineNumber]int line = 0, [CallerMemberName]string target = "")
{
Console.WriteLine(str);
Console.WriteLine(fileName);
Console.WriteLine(line);
Console.WriteLine(target);
}
}
#endregion
#region 系统自带特性——调用者信息特性
//哪个文件调用
//CallerFilePath特性
//哪一行调用
//CallerLineNumber特性
//哪个函数调用
//CallerMemberName特性
//需要引用命名空间 using System.Runtime.CompilerServices;
//一般作为函数参数的特性
#endregion
#region 系统自带特性——条件编译特性
//条件编译特性
//Conditional
//它会和预处理指令 #define 配合使用
//需要引用命名空间 using System.Diagnostics;
//主要可以用在一些调试代码上
//有时想执行有时不想执行的代码
//#define 函数名
//函数前面加 [Conditional("函数名")]
#endregion
#region 系统自带特性——外部Dll包函数特性
//DllImport
//用来标记非.Net(C#)的函数,表明该函数在一个外部的DLL中定义
//一般用来调用C或者C++的Dll包写好的方法
//需要引用命名空间 using System.Runtime.InteropServices;
//函数前面加 [DllImport("函数名")]
#endregion
class Program
{
[DllImport("Test.dll")]
public static extern int Add(int a, int b);
[Conditional("Fun")]
static void Fun()
{
Console.WriteLine("Fun执行");
}
static void Main(string[] args)
{
Console.WriteLine("特性");
#region 特性的使用
MyClass mc = new MyClass();
Type t = mc.GetType();
//t = typeof(MyClass);
//t = Type.GetType("lesson21-特性。MyClass");
//判断是否使用了某个特性
//参数一:代表特性的类型
//参数二:代表是否搜索继承链(属性和事件忽略此参数)
if (t.IsDefined(typeof(MyCustomAttribute), false))
{
Console.WriteLine("该类型应用了MyCustom特性");
}
object[]array=t.GetCustomAttributes(true);
for (int i = 0; i < array.Length; i++)
{
if (array[i] is MyCustomAttribute)
{
Console.WriteLine((array[i] as MyCustomAttribute).info);
(array[i] as MyCustomAttribute).TestFun();
}
}
TestClass tc = new TestClass();
//tc.OldSpeak("123");
tc.Speak();
tc.SpeakCaller("123123123");
Fun();
#endregion
}
}
//总结:
//特性是用于 为元数据再添加更多的额外信息(变量、方法等等)
//我们可以通过反射获取这些额外的数据 来进行一些特殊的处理
//自定义特性——继承Attribute
//系统自带特性:过时特性
//为什么要学特性
//Unity引擎中很多地方都用到了特性来进行一些特殊处理
}
特性练习题
using System;
namespace lesson21_特性练习题
{
#region 练习题1
//为反射练习题中的Player对象中的
//随便为其中一个成员变量加一个自定义特性
//同样实现反射练习题中的要求
//但是当在设置加了自定义特性的成员变量时,在控制台中打印一句
//非法操作,随意修改XXX成员
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("特性练习题");
}
}
}
22.迭代器
using System;
using System.Collections;
namespace lesson22_迭代器
{
#region 迭代器是什么
//迭代器(iterator)有时又称光标(cursor)
//是程序设计的软件设计模式
//迭代器模式提供一个方法顺序访问一个聚合对象中的各个元素
//而又不暴露其内部的标识
//在表现效果上看
//是可以在容器对象(例如链表或数组)上遍历访问的接口
//设计人员无需关心容器对象的内存分配的实现细节
//可以用foreach遍历的类,都是实现了迭代器的
#endregion
#region 标准迭代器的实现方法
//关键接口:IEnumeratory,IEnumerable
//命名空间:using System.Collections;
//可以通过同时继承 IEnumeratory 和 IEnumerable 实现其中的方法
class CustomList:IEnumerable,IEnumerator
{
private int[] list;
//从-1开始的光标 用于表示 数据得到了哪个位置
private int position = -1;
public CustomList()
{
list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
}
#region IEnumerable
public IEnumerator GetEnumerator()
{
Reset();
return this;
}
#endregion
public object Current
{
get
{
return list[position];
}
}
public bool MoveNext()
{
//移动光标
++position;
//是否溢出 溢出就不合法
return position < list.Length;
}
//reset是重置光标位置 一般写在获取
//用于第一次重置光标位置
public void Reset()
{
position = -1;
}
}
#endregion
#region 用yield return 语法糖实现迭代器
//yield return 是C#提供给我们的语法糖
//所谓语法糖,也称糖衣语法
//主要作用就是将复杂逻辑简单化,可以增加程序的可读性
//从而减少程序代码出错的机会
//关键接口:IEnumerable
//命名空间:using System.Collections;
//让想要通过foreach遍历的自定义类实现接口中的方法GetEnumerator即可
class CustomList2 : IEnumerable
{
private int[] list;
public CustomList2()
{
list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < list.Length; i++)
{
//yield关键字 配合迭代器使用
//可以理解为 暂时返回 保留当前的状态
//一会儿还会再回来
//C#的语法糖
yield return list[i];
}
}
}
#endregion
#region 用yield return 语法糖为泛型类实现迭代器
class CustomList : IEnumerable
{
private T[] array;
public CustomList(params T[] array)
{
this.array = array;
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < array.Length; i++)
{
yield return array[i];
}
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("迭代器");
CustomList list = new CustomList();
//foreach本质
//1.先获取in后面这个对象的 IEnumberator
// 会调用对象其中的 GetEnumerator 方法来获取
//2.执行得到这个 IEnumerator 对象中的 MoveNext 方法
//3.只要 MoveNext 方法的返回值是true 就会去得到 Current
// 然后复制给 item
//foreach (int item in list)
//{
// Console.WriteLine(item);
//}
//foreach (int item in list)
//{
// Console.WriteLine(item);
//}
CustomList2 list2 = new CustomList2();
foreach (int item in list2)
{
Console.WriteLine(item);
}
foreach (int item in list2)
{
Console.WriteLine(item);
}
CustomList list3 = new CustomList("123", "321", "333", "555");
foreach (string item in list3)
{
Console.WriteLine(item);
}
}
}
//总结
//迭代器就是可以让我们在外部直接通过 foreach 遍历对象中元素而不需要了解其结构
//主要的两种方式
//1.传统方式 继承两个接口 实现里面的方法
//2.用语法糖 yield return 去返回内容 只需要继承一个接口即可
}
迭代器练习题
using System;
using System.Collections;
namespace lesson22_迭代器练习题
{
#region 练习题1
//请为一个自定义类
//用两种方法让其可以被 foreach遍历
//第一种 标准迭代器
class Test:IEnumerable,IEnumerator
{
private int[] array;
private int position=-1;
public Test()
{
array = new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
}
public object Current
{
get
{
return array[position];
}
}
public IEnumerator GetEnumerator()
{
Reset();
return this;
}
public bool MoveNext()
{
position++;
return position < array.Length;
}
public void Reset()
{
position = -1;
}
}
//第二种 yield return 语法糖
class Test2 : IEnumerable
{
private int[] array;
public Test2()
{
array = new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < array.Length; i++)
{
yield return array[i];
}
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("迭代器练习题");
//第一种 标准迭代器
Test t1 = new Test();
foreach (int item in t1)
{
Console.WriteLine(item);
}
//第二种 yield return 语法糖
Test2 t2 = new Test2();
foreach (int item in t2)
{
Console.WriteLine(item);
}
}
}
}
23.特殊语法
using System;
using System.Collections.Generic;
namespace lesson23_特殊语法
{
class Person
{
private int money;
public bool sex;
public string Name
{
get => "于双";
set => sex = true;
}
public int Age
{
get;
set;
}
public Person(int money)
{
this.money = money;
}
public int Add(int x, int y) => x + y;
public void Speak(string str) => Console.WriteLine(str);
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("特殊语法");
#region var隐式类型
//var 是一种特殊的变量类型
//它可以用来表示任意类型的变量
//注意:
//1.var 不能作为类的成员 只能用于临时变量申明时
// 也就是 一般写在函数语句块中
//2.var 必须初始化
var i = 5;
var s = "123";
var array = new int[] { 1, 2, 3, 4, };
var list = new List();
//在类型不确定的情况下可以用 var 缺点 看代码时需要看后面代码才能确定var代表的类型
#endregion
#region 设置对象初始值
//申明对象时
//可以通过直接写大括号的形式初始化公共成员变量和属性
Person p = new Person (100){ sex=true,Age=18,Name="于双"};
Person p2 = new Person (200){ Age = 18 };
#endregion
#region 设置集合初始值
//申明集合对象时
//也可以通过大括号 直接初始化内部属性
int[] array2 = new int[] { 1, 2, 3, 4, 5 };
List listInt = new List() { 1, 2, 3, 4, 5 };
List listPerson = new List() {
new Person(100),
new Person(100) { Age=10},new Person(1){ sex=true,Name="于双"}
};
Dictionary dic = new Dictionary()
{
{ 1,"123"},
{ 2,"222"}
};
#endregion
#region 匿名类型
//var 变量可以申明为自定义的匿名类型
var v = new { age = 10, money = 11, name = "小明" };
Console.WriteLine(v.age);
Console.WriteLine(v.money);
Console.WriteLine(v.name);
#endregion
#region 可空类型
//1.值类型是不能赋值为 空的
//int c = null;
//2.申明时 在值类型后面加?可以赋值为空
int? c = null;
//3.判断是否为空
if (c.HasValue)
{
Console.WriteLine(c);
Console.WriteLine(c.Value);
}
//4.安全获取可空类型值
int? value = null;
// 4-1.如果为空 默认返回值类型的默认值
Console.WriteLine(value.GetValueOrDefault());
// 4-2.也可以指定一个默认值
Console.WriteLine(value.GetValueOrDefault(100));
Console.WriteLine(value);
float? f = null;
double? d = null;
object o = null;
if (o != null)
{
o.ToString();
}
//相当于是一种语法糖 能够帮助我们自动去判断是否为空
//如果是null 就不会执行toString 也不会报错
Console.WriteLine(o?.ToString());
int[] arrayInt = null;
//Console.WriteLine(arrayInt[0]);//会报错
Console.WriteLine(arrayInt?[0]);
Action action = null;
//if (action != null)
//{
// action();
//}
action?.Invoke();
#endregion
#region 空合并操作符
//空合并操作符 ??
//左边值 ?? 右边值
//如果左边值为null 就返回右边值 否则返回左边值
//只要是可以为null的类型都能用
int? intV = null;
//int intI = intV == null ? 100 : intV.Value;
//简写
int intI = intV ?? 100;
Console.WriteLine(intI);
string str = null;
str = str ?? "haha";
Console.WriteLine(str);
#endregion
#region 内插字符串
//关键符号:$
//用$来构造字符串,让字符串中可以拼接变量
string name = "于双";
int age = 18;
Console.WriteLine($"好好学习,{name},年龄:{age}");
#endregion
#region 单句逻辑简略写法
//当循环或者if语句中只有 一句代码时 大括号可以省略
if (true)
Console.WriteLine("123123");
for (int j = 0; j < 10; j++)
Console.WriteLine(j);
#endregion
}
}
}
冒泡排序
public static void sort(Integer[] param) {
for (int i = param.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
int current = param[j];
int next = param[j + 1];
方法一:
public class Zhidao {
public static void main(String args[]) {
String s = "sdf灭礌 kjl d{';\fdsjlk是";
int n=0;
for(int i=0; i<s.length(); i++) {
n = (int)s.charAt(i);
if((
IF OBJECT_ID('tempdb..#ABC') is not null
drop table tempdb..#ABC
create table #ABC
(
PATHNAME NVARCHAR(50)
)
insert into #ABC
SELECT N'/ABCDEFGHI'
UNION ALL SELECT N'/ABCDGAFGASASSDFA'
UNION ALL
http://www.sdn.sap.com/irj/boc/business-objects-for-sap-faq
Besides, I care that how to integrate tightly.
By the way, for BW consultants, please just focus on Query Designer which i
结构
继承关系
public static final class Manifest.permission_group extends Object
java.lang.Object
android. Manifest.permission_group 常量
ACCOUNTS 直接通过统计管理器访问管理的统计
COST_MONEY可以用来让用户花钱但不需要通过与他们直接牵涉的权限
D