有这些类
abstract class ElementBase
class RectElement : ElementBase{}
class EllipseElement : ElementBase{}如何编写一个ElementBase Create(string typeName)方法, 根据typeName去创建继承于ElementBase的类最好不要通过反射,有没有办法

解决方案 »

  1.   

    不要根据typeName去创建,用泛型好了
    public T Create<T>() where T : new()
    {
        return new T();
    }
      

  2.   

    我是要保存到xml,然后加载的时候必须通过name去创建
      

  3.   

    用简单工厂也可以.
    class ElementFactory
    {
        public static CreateElement(string typeName)
        {
              siwth(typeName)
              { 
                    case "....":
                        return new RectElement();
                    case ".....":
                        return new  EllipseElement ();          
               } 
        }
        
    }
      

  4.   


    这种方式缺点是代码写死了
    比如别人自己写了一个xxElement,继承ElementBase,那用ElementFactory.CreateElement就无法创建了
      

  5.   

    貌似只有用反射,而且前提是派生类最好是与基类在一个程序集中实际上你的思路是有问题的,因为基类根本就不应该知道关于派生类的任何事情!
    因为一个基类可能在任何时候被任何人用来派生无限多个派生类
    比如2012年某个人写了一个类SomeClass,派生自你这个ElementBase类
    而你现在就能创建这个SomeClass,难道你能未卜先知吗?
      

  6.   


    我不需要得到他的程序集,我只要他实现我需要的方法,比如
    Rectangle GetBounds()(用来计算选区)
    void Paint(Graphic g);(用来绘制)
      

  7.   

    我能想到的方法就是枚举所有加载的程序集,获取所有类型,从中查找所有实现ElementBase的类型来创建。
    但是这样太麻烦了,想看看大家有没有更简便的方法。
      

  8.   

    我说的你不明白啊?//我不需要得到他的程序集,我只要他实现我需要的方法
    你跑题了!他实现你需要的方法没有任何问题
    override的方式由于多态性自然会由各派生类实现但是你现在说的是创建的派生类实例
    这在基类中无法做到,而且也不应该由基类来做!
    如果一定要创建,你需要的是另外一个工厂类,而且实现方法只有反射~
      

  9.   

    最近我也处理过这样的问题,LZ写基类是不是用于以后派生类不用写太多相同的代码,或者说基类和派生类里的方法的返回值永远都是一样,只是派生类的方法有不同的算法所以返回的值不同?是不是想达到这样的目的?
    如果是这样其实用影射也很简单做到,目前我就是用这个方法。但需要注意的是:
    如果你的类不是在当前的装配件中定义的或者定义该类的装配件不是全局装配件,你需要先Load定义该类的装配件,Like:  
      System.Reflection.Assembly   a   =   System.Reflection.Assembly.Load("你的装配件的名称");    
      Type   tt   =   a.GetType("topNamingSpace.subNamingspace.className");下边是代码:
      

  10.   


    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");
            }
        }
    }
      

  11.   

    public static AbstractFactoty.AbstractFactoyt CreateFactoty()
            {
                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;
            }
      

  12.   

    想到一个比较简单的方法,缺点是自己继承的类在实现前要通过ElementBase.CreateInstance方法创建的话必须在使用前在name2CreateMap表内添加: public abstract class ElementBase : IFlowChartElement
    {
    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(); });
    }
    这种约定编译器无法检查了.有更好的办法么?
      

  13.   

    OOP要是能加一个static abstract就好了