本人从C++转到C#开发,将开发过程中遇到的两种语言的主要区别及C#的基础知识点,记录一下。
反射、插件式开发、工厂模式
1,反射(Reflection)可以在运行时获 得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。
2,常用于动态加载dll,相当于C++中的loadlibrary,比起静态加载,可以解耦,提高程序模块性。
3,例子
转自>https://www.cnblogs.com/LipeiNet/archive/2015/11/24/4990580.html
//获取当前执行代码的程序集
Assembly assem = Assembly.GetExecutingAssembly();
Console.WriteLine(assem.FullName);
var types = assem.GetTypes();//程序集下所有的类
Console.WriteLine("程序集包含的类型:");
foreach (var item in types) {
Console.WriteLine("类" + item.Name);
}
4,工厂模式举例:商店(调用者)买水果(苹果、香蕉(具体被调用对象)),商店不需要分别去买苹果和香蕉,而只需要告诉水果工厂(工厂)我需要的水果名称,该工厂就返回需要的水果给我。苹果和香蕉需要继承一个公共的水果基类。
转自>http://blog.youkuaiyun.com/u012116457/article/details/21650421
public class Store {
public static void main(String[] args) {
Frute a=Factory.getFrute("apple"); //得到产品对象
if(a!=null)
System.out.println(a.tell());
Frute b=Factory.getFrute("banana"); //得到产品对象
if(a!=null)
System.out.println(a.tell());
}
}
//工厂类
class Factory{
//只负责产生对象
public static Frute getFrute(String name){
if(name.equals("apple")){
return new Apple();
}else if(name.equals("banana")){
return new Banana();
}
return null;
}
}
interface Frute{
public String tell();
}
//苹果类
class Apple implements Frute{
public String tell(){
return "我是苹果";
}
}
//香蕉类
class Banana implements Frute{
public String tell(){
return "我是香蕉";
}
}
5,工厂模式下用反射加载dll
public static T Instance<T>(string assembly, string type)
{
if (string.IsNullOrEmpty(type)) throw new ArgumentException("type:参数不能为空!");
//1、获取有效的程序集
Assembly mAssembly = string.IsNullOrEmpty(assembly) ? Assembly.GetCallingAssembly() : Assembly.Load(assembly);
var t = (T) mAssembly.CreateInstance(type); //创建实例
return t;
}
其中,参数assembly 指的是程序dll的路径,参数type 指的是名称空间+类
6,插件式开发的核心思想就是:工厂模式下用反射加载dll(插件)。
委托、事件、观察者模式
1,委托类似于C++中的函数指针,由于本人有C++基础,不再重复记录。
2,事件可以看做是委托的一种形式。
3,事件常见的有系统事件(点击一个button,触发click事件)和自定义事件(常用于对象/线程间通信/消息传递,类似于windows消息中的sendmessage,postmessage,也类似于QT中的自定义信号与槽)。
4,C#事件与观察者设计模式结合结合紧密,下面是一个例子:
修改自>http://blog.youkuaiyun.com/susan19890313/article/details/6949738
现在假设三个独立的部分:热水器、警报器、显示器,它们来自于不同厂商并进行了组装。热水器(Subject:监视对象)仅仅负责烧水,它不能发出警报也不能显示水温;在水烧开时由警报器(Observer:观察者)发出警报、显示器(Observer:观察者)显示提示和水温。
Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的多个对象会被自动告知并更新(C#中通过事件实现)。
// 热水器
public class Heater {
private int temperature;
public string type = “Aliston″;
public string area = “China”;
//声明委托
public delegate void BoiledEventHandler(Object sender, BoliedEventArgs e);
public event BoiledEventHandler Boiled; //**定义事件**
// 定义BoliedEventArgs类,传递给Observer所感兴趣的信息
public class BoliedEventArgs : EventArgs
{
public readonly int temperature;
public BoliedEventArgs(int temperature)
{
this.temperature = temperature;
}
}
// 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视
protected virtual void OnBolied(BoliedEventArgs e)
{
if (Boiled != null)
{
Boiled(this, e);
}
}
public void BoilWater()
{
for (int i = 0; i <= 100; i++)
{
temperature = i;
{
BoliedEventArgs e = new BoliedEventArgs(temperature); .
OnBolied(e); // 触发事件
}
}
}
}
//警报器
public class Alarm {
public void MakeAlert(Object sender, Heater.BoliedEventArgs e) {
Heater heater = (Heater)sender;
//访问 sender 中的公共字段
Console.WriteLine(”Alarm:{0} - {1}: “, heater.area, heater.type);
Console.WriteLine(”Alarm: 嘀嘀嘀,水已经 {0} 度了:”, e.temperature);
Console.WriteLine();
}
}
//显示器
public class Display {
public static void ShowMsg(Object sender, Heater.BoliedEventArgs e) { //静态方法
Heater heater = (Heater)sender;
Console.WriteLine(”Display:{0} - {1}: “, heater.area, heater.type);
Console.WriteLine(”Display:水快烧开了,当前温度:{0}度。”, e.temperature);
Console.WriteLine();
}
}
class Program {
static void Main() {
Heater heater = new Heater();
Alarm alarm = new Alarm();
heater.Boiled += alarm.MakeAlert; //订阅事件
heater.Boiled += Display.ShowMsg; //订阅事件
heater.BoilWater();
}
}