显示接口实现
namespace MyLib.MyNamespace2
{
public class Program
{
static void Main(string[] args)
{
var wk = new WarmKiller();
wk.Love(); //这个时候只能看见love,不能看见kill的方法
IKiller killer = new WarmKiller();
killer.Kill(); //这个时候可以调用kill方法,但是看不见love
//如果需要调用的话,需要强转换
var wwk = (WarmKiller)killer;
wwk.Love();
}
}
interface IGentleman
{
void Love();
}
interface IKiller
{
void Kill();
}
class WarmKiller : IGentleman, IKiller
{
public void Love()
{
Console.WriteLine("I will love you for ever...");
}
//显示实现
void IKiller.Kill()
{
Console.WriteLine("Let me kill the enemy...");
}
}
}
反射与依赖注入
- 理解:尽可能的在动态的时候完成所需要干的事情(例如枚举n个,可以适应各种情况)
- 反射:以不变应万变(更松的耦合)
- 反射与接口的结合
- 反射与特性的结合
依赖注入
namespace MyLib.MyNamespace2
{
public class Program
{
static void Main(string[] args)
{
//这个一般不会直接用
/*
ITank tank = new HeavyTank();
// ================华丽的分割线==================
//下面都不用静态类型
var t = tank.GetType();
object o = Activator.CreateInstance(t); //不知道t里面有什么东西,但是指定t里面有2个方法
MethodInfo fireMi = t.GetMethod("Fire");
MethodInfo runMi = t.GetMethod("Run");
fireMi.Invoke(o, null);
runMi.Invoke(o, null);
*/
//
//封装好的反射
//
//有一个容器,把所有的东西都放进去
//一次性注入
var sc = new ServiceCollection();
sc.AddScoped(typeof(ITank), typeof(HeavyTank)); //修改HeavyTank就可以改变实例,如果是用new的话,有多少个new就得改多少次
sc.AddScoped(typeof(IVehicle), typeof(Car));
sc.AddScoped<Driver>();
var sp = sc.BuildServiceProvider(); //注册
//==================华丽的分割线===================
ITank tank = sp.GetService<ITank>(); //注册tank实例
tank.Fire();
tank.Run();
var driver = sp.GetService<Driver>();
driver.Drive();
}
}
class Driver
{
private IVehicle _vehicle;
public Driver(IVehicle vehicle)
{
_vehicle = vehicle;
}
public void Drive()
{
_vehicle.Run();
}
}
interface IVehicle
{
void Run();
}
class Car : IVehicle
{
public void Run()
{
Console.WriteLine("Car is running...");
}
}
class Truck : IVehicle
{
public void Run()
{
Console.WriteLine("Truck is running...");
}
}
interface IWeapon
{
void Fire();
}
//一个接口对多个接口的继承
interface ITank : IVehicle, IWeapon
{
/*
void Fire();
void Run();
*/
}
class LightTank : ITank
{
public void Fire()
{
Console.WriteLine("Boom!");
}
public void Run()
{
Console.WriteLine("ka ka ka......");
}
}
class MediumTank : ITank
{
public void Fire()
{
Console.WriteLine("Boom!!");
}
public void Run()
{
Console.WriteLine("ka! ka! ka!......");
}
}
class HeavyTank : ITank
{
public void Fire()
{
Console.WriteLine("Boom!!!");
}
public void Run()
{
Console.WriteLine("ka!! ka!! ka!!......");
}
}
}
sdk,以及后续开发
namespace BabyStroller.App
{
internal class Program
{
static void Main(string[] args)
{
var folder = Path.Combine(Environment.CurrentDirectory, "Animals");
var files = Directory.GetFiles(folder);
var animalTypes = new List<Type>();
foreach(var file in files)
{
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(file);
var types = assembly.GetType();
foreach (var t in types)
{
if(t.GetMethod("Voice") != null)
{
animalTypes.Add(t);
}
}
}
while (true)
{
for (int i = 0; i < animalTypes.Count; i++)
{
Console.WriteLine($"{i + 1}.{animalTypes[i].Name}");
}
Console.WriteLine("======================");
Console.WriteLine("Please choose animal");
int index = int.Parse(Console.ReadLine());
if(index > animalTypes.Count || index < 1)
{
Console.WriteLine("No such an animal.Try again!");
continue;
}
int times = int.Parse(Console.ReadLine());
var t = animalTypes[index - 1];
var m = t.GetMethod("Voice");
var o = Activator.CreateInstance(t);
m.Invoke(o, new object[] { times });
}
}
}
}