首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

c# 工场模式 类名 转对象

2012-07-24 
c#工厂模式类名 转对象方式一:通过类名来生成对象(优势:方便;劣势:不能以递增方式增加需转化成对象的类文

c# 工厂模式 类名 转对象
方式一:通过类名来生成对象(优势:方便;劣势:不能以递增方式增加需转化成对象的类文件,即每次发布需整个项目重新编译)经测试正确

public class FruitFactory
{
 public IFruit MakeFruit(string Name)
 {
  IFruit MyFruit = null;
  try
  {
   Type type = Type.GetType(Name,true);
   MyFruit = (IFruit)Activator.CreateInstance(type);
  }
  catch (TypeLoadException e)
   Console.WriteLine("I dont know this kind of fruit,exception caught - {0}" ,e.Message);
   return MyFruit;
 }
}


方式二:通过反射(需提供文件路径,类名;优势:可以以递增文件的方式发布程序;劣势:生成文件麻烦)未测试
/// <summary>
        /// 创建对象(外部程序集)
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="typeName">类型名</param>
        /// <returns>创建的对象,失败返回 null</returns>
        public static object CreateObject(string path, string typeName)
        {
            object obj = null;
            try
            {

                obj = Assembly.Load(path).CreateInstance(typeName);
            }
            catch (Exception ex)
            {
                Debug.Write(ex);
            }


另外参见:http://blog.hetaoos.com/archives/40
C# 中反射获取某类的子类和根据类型名动态创建对象
2010/10/11 于 23:35 Null 已有 7 条评论

有时候,为了快速批量处理已经实现某个基类或者某个接口的子类,需要通过反射的方式获取到他们的类类型(Type),然后再通过
1Activator.CreateInstance(objType);

或者
1Assembly.Load(path).CreateInstance(typeName);

或者
1Assembly.LoadFile(filePath).CreateInstance(typeName);

创建对象实例。

以下通过一个简单的示例来展示:
1,获取当前程序集中的全部类型;
2,判断某一类型是否是继承与另一类型;
3,根据类型名动态创建对象。

目前还有个疑问,不知道谁能解答:
1,如何判断某个类是否实现了某个接口,目前只能先 new 一个对象,然后再 用 is 判断。
001using System;
002using System.Collections.Generic;
003using System.Text;
004using System.Reflection;
005using System.Diagnostics;
006
007namespace com.hetaoos
008{
009
010    class Test
011    {
012        public Test()
013        {
014            var types = Assembly.GetExecutingAssembly().GetTypes();
015            var baseType = typeof(BaseProcessor);
016            List<BaseProcessor> processors = new List<BaseProcessor>();
017            foreach (var t in types)
018            {
019                var tmp = t.BaseType;
020                while (tmp != null)
021                {
022                    if (tmp == baseType)
023                    {
024                        BaseProcessor obj = MethodMaker.CreateObject(t.FullName) as BaseProcessor;
025                        if (obj != null)
026                        {
027                            processors.Add(obj);
028                        }
029                        break;
030                    }
031                    else
032                    {
033                        tmp = tmp.BaseType;
034                    }
035                }
036            }
037
038            Debug.Print("Processor Count:{0}", processors.Count);
039            foreach (var p in processors)
040            {
041                Debug.Print("{0}\t:{1}", p, p.Calc(2, 5));
042            }
043        }
044    }
045
046    public class MethodMaker
047    {
048
049        /// <summary>
050        /// 创建对象(当前程序集)
051        /// </summary>
052        /// <param name="typeName">类型名</param>
053        /// <returns>创建的对象,失败返回 null</returns>
054        public static object CreateObject(string typeName)
055        {
056            object obj = null;
057            try
058            {
059                Type objType = Type.GetType(typeName, true);
060                obj = Activator.CreateInstance(objType);
061            }
062            catch (Exception ex)
063            {
064                Debug.Write(ex);
065            }
066            return obj;
067        }
068
069        /// <summary>
070        /// 创建对象(外部程序集)
071        /// </summary>
072        /// <param name="path"></param>
073        /// <param name="typeName">类型名</param>
074        /// <returns>创建的对象,失败返回 null</returns>
075        public static object CreateObject(string path, string typeName)
076        {
077            object obj = null;
078            try
079            {
080
081                obj = Assembly.Load(path).CreateInstance(typeName);
082            }
083            catch (Exception ex)
084            {
085                Debug.Write(ex);
086            }
087
088            return obj;
089        }
090    }
091
092    public abstract class BaseProcessor
093    {
094        public abstract int Calc(int a, int b);
095    }
096
097    public class Adder : BaseProcessor
098    {
099        public override int Calc(int a, int b)
100        {
101            return a + b;
102        }
103    }
104
105    public class Multiplier : BaseProcessor
106    {
107        public override int Calc(int a, int b)
108        {
109            return a * b;
110        }
111    }
112}

输出结果为:
1Processor Count:2
2com.hetaoos.Adder   :7
3com.hetaoos.Multiplier  :10

PS:
判断某个类是否继承自某个接口、类的方法:
01public static bool IsParent(Type test, Type parent)
02{
03    if (test == null || parent == null || test == parent || test.BaseType == null)
04    {
05        return false;
06    }
07    if (parent.IsInterface)
08    {
09        foreach (var t in test.GetInterfaces())
10        {
11            if (t == parent)
12            {
13                return true;
14            }
15        }
16    }
17    else
18    {
19        do
20        {
21            if (test.BaseType == parent)
22            {
23                return true;
24            }
25            test = test.BaseType;
26        } while (test != null);
27
28    }
29    return false;

            return obj;
        }

热点排行