假设有一个abstract基类:
abstract class BaseClass
{
public abstract string Name { get;}
}然后由它继承得到若干派生类:
class D1 : BaseClass
{
public override string Name { get { return "D1"; } }
}
class D2 : BaseClass
{
public override string Name { get { return "D2"; } }
}
/* D3,D4,... */现在需要一个函数,根据参数中给出的类的名字构造对应的派生类对象。它的代码可能像下面这样:
BaseClass CreateInstance(string ClassName)
{
switch (ClassName)
{
case "D1": return new D1();
case "D2": return new D2();
/* D3,D4,... */
}
return null;
}由于派生类比较多,如果用switch来写,代码的输入和调试都将成为不小的负担。现在请问,是否有一种方法简化这个CreateInstance函数?我想,我需要的函数可能像下面这个样子(伪代码表示)
BaseClass CreateInstance(string ClassName)
{
Type[] types = BassClass的所有派生类的Type;
foreach(Type t in types)
{
string s = 一个t类型的实例的Name属性值;
if( s == ClassName )
return 一个t类型的实例;
}
return null;
}以前C++中我也想过类似问题,但当时没能解决。感觉C#的反射机制功能很多,不知道能否实现?
望各位指点,小弟谢过。
abstract class BaseClass
{
public abstract string Name { get;}
}然后由它继承得到若干派生类:
class D1 : BaseClass
{
public override string Name { get { return "D1"; } }
}
class D2 : BaseClass
{
public override string Name { get { return "D2"; } }
}
/* D3,D4,... */现在需要一个函数,根据参数中给出的类的名字构造对应的派生类对象。它的代码可能像下面这样:
BaseClass CreateInstance(string ClassName)
{
switch (ClassName)
{
case "D1": return new D1();
case "D2": return new D2();
/* D3,D4,... */
}
return null;
}由于派生类比较多,如果用switch来写,代码的输入和调试都将成为不小的负担。现在请问,是否有一种方法简化这个CreateInstance函数?我想,我需要的函数可能像下面这个样子(伪代码表示)
BaseClass CreateInstance(string ClassName)
{
Type[] types = BassClass的所有派生类的Type;
foreach(Type t in types)
{
string s = 一个t类型的实例的Name属性值;
if( s == ClassName )
return 一个t类型的实例;
}
return null;
}以前C++中我也想过类似问题,但当时没能解决。感觉C#的反射机制功能很多,不知道能否实现?
望各位指点,小弟谢过。
从程序集取得所有属于class的type
再判断type中你需要的名称然后构造,转化成父类型返回就行了。
在一本C#的设计模式的书里,这个叫:“反射工厂”本人不建议这么做。创建型模式那么多,根据具体的应用应该有更好的选择。
示例
using System;
using System.Reflection;
public class LoadInvoke
{
public static void Main(string[] args)
{
Assembly a = Assembly.LoadFrom(args[0]);
Type[] mytypes = a.GetTypes();
BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach(Type t in mytypes)
{
MethodInfo[] mi = t.GetMethods(flags);
Object obj = Activator.CreateInstance(t); foreach(MethodInfo m in mi)
{
m.Invoke(obj, null);
}
}
}
}
《反射, 动态使用类型》
===================================
谢谢你的建议。
我也是这样想的,以前C++遇到这个问题时我就换了思路绕过去了。但现在新学C#,是出于好奇才想这样做的。本来这也不是什么大的工程项目,练习而已。
我已经照着Eddie005()的代码自己写了一个:
public static Skill Parse(string SkillName)
{
Type SkillType = typeof(Skill);
Assembly a = Assembly.GetAssembly(SkillType);
Type[] types = a.GetTypes();
foreach (Type t in types)
{
if (t.IsAbstract || !t.IsSubclassOf(SkillType))
continue;
Skill skill = (Skill)Activator.CreateInstance(t);
if (skill.Name == SkillName)
return skill;
}
throw new Exception("没有合适的技能");
}
由于Skill的各个派生类都只有一个Int32类型的成员,所以构造对象的代价并不大,我想在我的程序应该是适合使用的。谢谢几位了。
(大家没新的意见的话,我过段时间就结帖。)
这个已经创建了类的实例了吧?