熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

動態代碼的使用(反射和動態生成類)

2013-11-13 10:16:19  來源: .NET編程 

  在軟件開發尤其是框架和底層開發時為了更靈活的控制代碼常常需要進行一些動態的操作比如根據用戶的輸入等動態的調用類中的方法或者根據數據庫表結構用戶要求動態的生成一些類然後再動態的調用類中的方法當然使用這些方式時會對性能有一點影響具體使用過程中可以根據實際情況來定不過一般的B/S開發中主要的瓶頸還是在數據庫操作和網速方面這點影響應該可以忽略的

  反射的使用
    可以使用反射動態地創建類型的實例將類型綁定到現有對象或從現有對象中獲取類型然後可以調用類型的方法或訪問其字段和屬性
    需要使用的命名空間SystemReflection
    反射的作用很多下面的例子主要是看一下怎麼動態的調用類中的方法
    例子類
    class ReflTest
    {
        private string _prop;

  public string Prop
        {
            get { return _prop; }
            set { _prop = value; }
        }

  public void Write(string strText)
        {
            ConsoleWriteLine(\:\ + strText);
        }
        public void Write(string strText)
        {
            ConsoleWriteLine(\:\ + strText);
        }
        public void MyWrite(string strText)
        {
            ConsoleWriteLine(\:\ + strText);
        }
    }
這個例子中提供了三個方法和一個屬性下面的代碼來動態的調用它們
            string strText = \abcd\;

  BindingFlags flags = (BindingFlagsNonPublic | BindingFlagsPublic |
                BindingFlagsStatic | BindingFlagsInstance | BindingFlagsDeclaredOnly);

  Type t = typeof(ReflTest);
            MethodInfo[] mi = tGetMethods(flags);
            Object obj = ActivatorCreateInstance(t);

  foreach (MethodInfo m in mi)
            {
                if (mNameStartsWith(\Write\))
                {
                    mInvoke(obj new object[] { strText });
                } [Page]
            }

  MethodInfo mMy = tGetMethod(\MyWrite\);
            if (mMy != null)
            {
                mMyInvoke(obj new object[] { strText });
            }
    BindingFlags用來設置要取得哪些類型的方法然後我們就可以取得這些方法來動態的調用(當然為了可以循環的調用方法在方法的命名方面可以自己指定一個規則)

  動態生成類
    我們可以在程序運行過程中調用NET中提供的編譯類動態的將一段string編譯成一個類然後再通過反射來調用它
    需要使用的命名空間SystemCodeDom SystemCodeDomCompiler MicrosoftCSharp SystemReflection

  動態創建編譯類的代碼如下
        public static Assembly NewAssembly()
        {
            //創建編譯器實例
            provider = new CSharpCodeProvider();
            //設置編譯參數
            paras = new CompilerParameters();
            parasGenerateExecutable = false;
            parasGenerateInMemory = true;

  //創建動態代碼
            StringBuilder classSource = new StringBuilder();
            classSourceAppend(\public   class   DynamicClass \\n\);
            classSourceAppend(\{\\n\);

  //創建屬性
            classSourceAppend(propertyString(\aaa\));
            classSourceAppend(propertyString(\bbb\));
            classSourceAppend(propertyString(\ccc\));

  classSourceAppend(\}\);

  SystemDiagnosticsDebugWriteLine(classSourceToString());

  //編譯代碼
            CompilerResults result = providerCompileAssemblyFromSource(paras classSourceToString());

  //獲取編譯後的程序集
            Assembly assembly = resultCompiledAssembly; [Page]

  return assembly;
        }

  private static string propertyString(string propertyName)
        {
            StringBuilder sbProperty = new StringBuilder();
            sbPropertyAppend(\ private   int   _\ + propertyName + \   =   ;\\n\);
            sbPropertyAppend(\ public   int   \ + \\ + propertyName + \\\n\);
            sbPropertyAppend(\ {\\n\);
            sbPropertyAppend(\ get{   return   _\ + propertyName + \;}   \\n\);
            sbPropertyAppend(\ set{   _\ + propertyName + \   =   value;   }\\n\);
            sbPropertyAppend(\ }\);
            return sbPropertyToString();
        }propertyString方法就是用來拼寫字符串的
    整個代碼比較簡單主要步驟就是拼寫類的字符串  調用CSharpCodeProvider類進行編譯得到程序集(assembly)

  接下來就可以利用之前反射的方法來動態調用這個類中的屬性了
            Assembly assembly = NewAssembly();

  object Class = assemblyCreateInstance(\DynamicClass\);
            ReflectionSetProperty(Class \aaa\ );
           
            ReflectionGetProperty(Class \aaa\);

  object Class = assemblyCreateInstance(\DynamicClass\);
            ReflectionSetProperty(Class \bbb\ );
            ReflectionGetProperty(Class \bbb\);
    DynamicClass是我動態類的類名aaa和bbb是其中的屬性
    ReflectionSetProperty和ReflectionGetProperty代碼如下
    給屬性賦值
        private static void ReflectionSetProperty(object objClass string propertyName int value)
        {
            PropertyInfo[] infos = objClassGetType()GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if (infoName == propertyName && infoCanWrite) [Page]
                {
                    infoSetValue(objClass value null);
                }
            }
        }
    取得屬性的值
        private static void ReflectionGetProperty(object objClass string propertyName)
        {
            PropertyInfo[] infos = objClassGetType()GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if (infoName == propertyName && infoCanRead)
                {
                    SystemConsoleWriteLine(infoGetValue(objClass null));
                }
            }
        }


From:http://tw.wingwit.com/Article/program/net/201311/13126.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.