有这些类
abstract class ElementBase
class RectElement : ElementBase{}
class EllipseElement : ElementBase{}如何编写一个ElementBase Create(string typeName)方法, 根据typeName去创建继承于ElementBase的类最好不要通过反射,有没有办法
abstract class ElementBase
class RectElement : ElementBase{}
class EllipseElement : ElementBase{}如何编写一个ElementBase Create(string typeName)方法, 根据typeName去创建继承于ElementBase的类最好不要通过反射,有没有办法
public T Create<T>() where T : new()
{
return new T();
}
class ElementFactory
{
public static CreateElement(string typeName)
{
siwth(typeName)
{
case "....":
return new RectElement();
case ".....":
return new EllipseElement ();
}
}
}
这种方式缺点是代码写死了
比如别人自己写了一个xxElement,继承ElementBase,那用ElementFactory.CreateElement就无法创建了
因为一个基类可能在任何时候被任何人用来派生无限多个派生类
比如2012年某个人写了一个类SomeClass,派生自你这个ElementBase类
而你现在就能创建这个SomeClass,难道你能未卜先知吗?
我不需要得到他的程序集,我只要他实现我需要的方法,比如
Rectangle GetBounds()(用来计算选区)
void Paint(Graphic g);(用来绘制)
但是这样太麻烦了,想看看大家有没有更简便的方法。
你跑题了!他实现你需要的方法没有任何问题
override的方式由于多态性自然会由各派生类实现但是你现在说的是创建的派生类实例
这在基类中无法做到,而且也不应该由基类来做!
如果一定要创建,你需要的是另外一个工厂类,而且实现方法只有反射~
如果是这样其实用影射也很简单做到,目前我就是用这个方法。但需要注意的是:
如果你的类不是在当前的装配件中定义的或者定义该类的装配件不是全局装配件,你需要先Load定义该类的装配件,Like:
System.Reflection.Assembly a = System.Reflection.Assembly.Load("你的装配件的名称");
Type tt = a.GetType("topNamingSpace.subNamingspace.className");下边是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;using System.Reflection;namespace ConsoleApplication_dynamic_obj
{
class Program
{
static void Main(string[] args)
{
//Exe_Class("test");
Exe_Class("test");
} static void Exe_Class(string class_name)
{
try
{
//获取类型信息
Type t = Type.GetType("ConsoleApplication_dynamic_obj." + class_name);
//根据类型创建对象
object[] parameters_b = new object[] { "Hello" };
object obj = Activator.CreateInstance(t, parameters_b);
//方法参数
object[] parameters = new object[] { "Hello" ,10};
//非静态方法调用
//t.InvokeMember("start1", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, obj, parameters);
//静态方法调用
t.InvokeMember("start1", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, obj, parameters);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
} public class test
{
public test(string k)
{
Console.WriteLine("test:"+k);
} public void start(string kk,int j)
{
Console.WriteLine("test:start:"+kk+j.ToString());
} public static void start1(string kk, int j)
{
Console.WriteLine("test:start:" + kk + j.ToString());
}
} public class test1
{
public test1()
{
Console.WriteLine("test1");
} public void start()
{
Console.WriteLine("test1:start");
}
}
}
{
AbstractFactoyt factoty = null;
string DBType = ConfigurationSettings.AppSettings["DBType"].ToString();
//switch语句可以根据用于选择什么样的数据库调用执行相应的操作
switch (DBType)
{
case "Sql":
factoty = (AbstractFactoyt)Assembly.Load("AbstractFactoty").CreateInstance("MyStudent.DAL.AbstractFactoty." +DBType);
break;
case "Access":
//factoty = (AbstractFactoyt)Assembly.Load("AbstractFactoty").CreateInstance("MyStudent.DAL.AbstractFactoty.AccessFactoty");
break;
}
return factoty;
}
{
protected delegate IFlowChartElement CreateInstanceInvoker();
protected static Dictionary<string, CreateInstanceInvoker> name2CreateMap = new Dictionary<string, CreateInstanceInvoker>();
public static IFlowChartElement CreateInstance(string name)
{
try
{
return name2CreateMap[name].Invoke();
}
catch (KeyNotFoundException knfEx) { throw new KeyNotFoundException(name + " 未定义类型,请先添加name2CreateMap的映射", knfEx); }
}
static ElementBase()
{
name2CreateMap.Add(typeof(RectElement).Name, delegate { return new RectElement(); });
name2CreateMap.Add(typeof(EllipseElement).Name, delegate { return new EllipseElement(); });
}
比如在Program.cs中加入
static Program()
{
ElementBase.name2CreateMap.Add(typeof(XXElement).Name, delegate { return new XXElement(); });
}
这种约定编译器无法检查了.有更好的办法么?