浅谈反射
这样子的其实没有用到c#中的三大特性,封装,继承,多态
下面演示一下封装
using System;
namespace styde03
{
class Program
{
static void Main(string[] args)
{
//计算器的应用场景
Console.WriteLine(“第一个数字”);
int figure1 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(“请输入字符”);
string symbol = Console.ReadLine();
Console.WriteLine(“第一个数字”);
int figure2 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(operation(figure1, figure2, symbol));
}
public static int operation(int figure1,int figure2,string symbol)
{
switch (symbol)
{
case “*”: return new Multiplication().carculator(figure1,figure2); break;
case “+”: return new addition().carculator(figure1,figure2); break;
case “-“: return new Subtraction().carculator(figure1,figure2); break;
case “/”: return new Division().carculator(figure1,figure2); break;
default:
return 0;
break;
}
}
}
}
//然后创建一个接口,来规定方法里面
namespace styde03
{
interface carculatorInterface
{
public int carculator(int figure1,int figure2);
}
}
//创建加法的实现类
namespace styde03
{
class addition : carculatorInterface
{
public int carculator(int figure1,int figure2)
{
return figure1 + figure2;
}
}
}
//创建减法的实现类
namespace styde03
{
class Subtraction : carculatorInterface
{
public int carculator(int figure1, int figure2)
{
return figure1 – figure2;
}
}
}
//创建除法的实现类
namespace styde03
{
class Division : carculatorInterface
{
public int carculator(int figure1, int figure2)
{
return figure1 / figure2;
}
}
}
//创建乘法的实现类
namespace styde03
{
class Multiplication : carculatorInterface
{
public int carculator(int figure1, int figure2)
{
return figure1 * figure2;
}
}
}
这样的话,不管你要添加什么样子的运算,我只需要在operation方法的switch里面一个,然后在加一个类,调用接口就可以了
但是这样的话,虽然简介,但是还是一个不完全的简单工厂类所以我又换了一种写法
using System;
namespace styde03
{
class Program
{
static void Main(string[] args)
{
//计算器的应用场景
Console.WriteLine(“第一个数字”);
int figure1 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(“请输入字符”);
string symbol = Console.ReadLine();
Console.WriteLine(“第一个数字”);
int figure2 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(operation(figure1, figure2, symbol).Combination());
}
public static carculator operation(int figure1,int figure2,string symbol)
{
carculator car = null;
switch (symbol)
{
case “*”:
Muitiplication1 mui = new Muitiplication1(figure1, figure2);
car = mui;
break;
case “+”:
addition1 add = new addition1(figure1, figure2);
car= add;
; break;
case “-“:
Subetation1 cub = new Subetation1(figure1, figure2);
car = cub;
; break;
case “/”:
division1 div = new division1(figure1, figure2);
car = div;
; break;
}
return car;
}
}
}
创建一个抽象类,来写四个方法
namespace styde03
{
public abstract class carculator
{
public abstract int Combination();
}
}
//创建一个实现抽象类的抽象方法
namespace styde03
{
class addition1 :carculator
{
private int Figure1;
private int Figure2;
public addition1(int figure1, int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 + Figure2;
}
}
class division1 : carculator
{
private int Figure1;
private int Figure2;
public division1(int figure1,int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 / Figure2;
}
}
class Muitiplication1 : carculator
{
private int Figure1;
private int Figure2;
public Muitiplication1(int figure1, int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 * Figure2;
}
}
class Subetation1 : carculator
{
private int Figure1;
private int Figure2;
public Subetation1(int figure1, int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 – Figure2;
}
}
}
这样子继承用上了,多态用了,封装也用上了完全的符合c#工厂模式,现在要是想加一个运算就在实现抽象类的抽象方法
里加一个实现抽象方法的和if里的判断语句
但是这样子还是有点麻烦,下面实现一下简单的策略模式
using System;
namespace styde03
{
class Program
{
static void Main(string[] args)
{
//计算器的应用场景
Console.WriteLine(“第一个数字”);
int figure1 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(“请输入字符”);
string symbol = Console.ReadLine();
Console.WriteLine(“第一个数字”);
int figure2 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(operation(figure1, figure2, symbol));
}
public static int operation(int figure1,int figure2,string symbol)
{
carculator car = null;
switch (symbol)
{
case “*”:
return new dbContent(new Muitiplication1(figure1, figure2)).getrusult();
break;
case “+”:
return new dbContent(new addition1(figure1, figure2)).getrusult();
; break;
case “-“:
return new dbContent(new Subetation1(figure1, figure2)).getrusult();
; break;
case “/”:
return new dbContent(new Subetation1(figure1, figure2)).getrusult();
; break;
}
return 0;
}
}
}
加一个dbcontent类,然后让他来操作类以及值的变化
namespace styde03
{
class dbContent
{
private carculator Car;
public dbContent(carculator car) {
this.Car = car;
}
public int getrusult()
{
return Car.Combination();
}
}
}
然后创建抽象类
namespace styde03
{
abstract class carculator
{
public abstract int Combination();
}
}
实现抽象类的方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace styde03
{
class addition1 :carculator
{
private int Figure1;
private int Figure2;
public addition1(int figure1, int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 + Figure2;
}
}
class division1 : carculator
{
private int Figure1;
private int Figure2;
public division1(int figure1,int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 / Figure2;
}
}
class Muitiplication1 : carculator
{
private int Figure1;
private int Figure2;
public Muitiplication1(int figure1, int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 * Figure2;
}
}
class Subetation1 : carculator
{
private int Figure1;
private int Figure2;
public Subetation1(int figure1, int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 – Figure2;
}
}
}
从上面的代码,你会发现就加了一个dbcontent类,也没有做什么,但是我们已经把一个加减乘除从一开始的一个模块,
划分了四个模块,一个是输入模块,一个是判断模块,一个是dbcontent模块,一个是抽象模块,哪里出了问题就可以很好的解决了
其实这个代码不是最简单的,最简单的是只加一个方法,不用加switch,也可以出来你想要的运算答案,下面进入代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace styde03
{
[algorithmAttribute(“+”, “addition1”)]
class addition1 :carculator
{
private int Figure1;
private int Figure2;
public addition1(int figure1, int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 + Figure2;
}
}
[algorithmAttribute(“/”, “division1”)]
class division1 : carculator
{
private int Figure1;
private int Figure2;
public division1(int figure1,int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 / Figure2;
}
}
[algorithmAttribute(“*”, “Muitiplication1”)]
class Muitiplication1 : carculator
{
private int Figure1;
private int Figure2;
public Muitiplication1(int figure1, int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 * Figure2;
}
}
[algorithmAttribute(“-“, “Subetation1”)]
class Subetation1 : carculator
{
private int Figure1;
private int Figure2;
public Subetation1(int figure1, int figure2)
{
this.Figure1 = figure1;
this.Figure2 = figure2;
}
public override int Combination()
{
return Figure1 – Figure2;
}
}
public class algorithmAttribute : System.Attribute
{
public string Symbol;
public string Name;
public algorithmAttribute(string symbol,string name)
{
this.Symbol = symbol;
this.Name = name;
}
}
}
利用反射去除了if和else
using System;
using System.Reflection;
namespace styde03
{
class Program
{
static void Main(string[] args)
{
//计算器的应用场景
Console.WriteLine(“第一个数字”);
int figure1 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(“请输入字符”);
string symbol = Console.ReadLine();
Console.WriteLine(“第一个数字”);
int figure2 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(operation(figure1, figure2, symbol));
//特性和反射
}
public static int operation(int figure1,int figure2,string symbol)
{
int returnValue = 0;
//加载程序集
Assembly ass = Assembly.Load(“styde03”);
//获取程序集中的所有方法
foreach (Type item in ass.GetTypes())
{
//获取类型的特性
var re= item.GetCustomAttribute<algorithmAttribute>();
if (re==null)
{
continue;
}
//看类中的特性是不是和我输入的字符一直
if (re.Symbol==symbol )
{
//要是就创建这个类进行调用里面的方法
//创建实例的参数
//创建实例要的参数
object[] constuctParms = new object[] {figure1,figure2 };
//创建实例
object dObj = Activator.CreateInstance(item, constuctParms);
//获取方法的信息
MethodInfo method = item.GetMethod(“Combination”);
//调用方法的一些标志位,这里的含义是Public并且是实例方法,这也是默认的值
BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;
//方法的参数
//object[] parameters = new object[] { “Hello” };
//调用方法,返回的是一个onject类型
returnValue = (int) method.Invoke(dObj, flag, Type.DefaultBinder, null, null);
}
}
return returnValue;
}
}
}
抽象类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace styde03
{
abstract class carculator
{
public abstract int Combination();
}
}
这个代码里,其实不是最简单的,最简单的是枚举进行名字的对应关系,但是枚举不能用符号,所以用了特性,但是我这个反射不推荐大家使用,我这个反射对于性能来说,不是很好,这个实例没有弄好
其实你项目中要是有缓存的话,最好用Dictionary把对应关系存储起来,然后是什么符号直接用key来找到values,这样的话,就好找多了,要是没有用到缓存,还要存数据,这样有点浪费步骤,所以我用到了特性。
你要记住反射可以只要一个名字,也就是字符窜就可以调用类的方法,属性,特性,公有的方法,和私有的方法。