1.新建項目,命名爲0331使用動態類和反射設置某個類中的變量值(好變態的中文項目名!)
2.添加引用,將someInterface和標記屬性添加進來。
3.添加一個類,名爲dynamic.cs;該類即爲實現動態類生成的類。
主要包含三個功能,一是動態的編寫出來代碼,二是編寫編譯選項;三是執行編譯,生成類庫。代碼不做詳細介紹了,自己去補codeDOM相關知識。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using Microsoft.CSharp;
using System.Collections;
namespace _0331使用動態類和反射設置某個類中的變量值
{
//忘了爲什麼使用靜態類了,沒測試其他的行不行
public static class dynamic
{
//生成類的代碼
public static CompilerResults compileCode(string sourceCSFile,string dllName)
{
CSharpCodeProvider compiler = new CSharpCodeProvider(
new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.Data.dll");
cp.ReferencedAssemblies.Add(dllName);
cp.ReferencedAssemblies.Add("someInterface.dll");
cp.OutputAssembly = "dynamic.dll";
cp.GenerateExecutable = false;
CompilerResults cr = compiler.CompileAssemblyFromFile(cp, sourceCSFile);
return cr;
}
//生成類的代碼,帶參數
private static CodeCompileUnit CompileUnit(string fullClassName, ArrayList fields)
{
CodeCompileUnit compunit = new CodeCompileUnit();
CodeNamespace sample = new CodeNamespace("dynamicNS");
CodeTypeDeclaration myclass = new CodeTypeDeclaration("dynamicClass");
#region 設置變量值的函數
CodeMemberMethod setValues = new CodeMemberMethod();
setValues.Name = "setValues";
setValues.Attributes = MemberAttributes.Public | MemberAttributes.Final;
CodeParameterDeclarationExpression cp2 = new CodeParameterDeclarationExpression("System.Object", "obj");
setValues.Parameters.Add(cp2);
CodeVariableDeclarationStatement cv2 = DeclareVariables(fullClassName, "dllClass");
setValues.Statements.Add(cv2);
CodeTypeReference ct = new CodeTypeReference(fullClassName);
CodeAssignStatement dllclass = new CodeAssignStatement(new CodeVariableReferenceExpression("dllClass"), new CodeCastExpression(fullClassName, new CodeVariableReferenceExpression("obj")));
setValues.Statements.Add(dllclass);
for (int i = 0; i < fields.Count; i = i + 3)
{
string name = "dllClass." + fields[i].ToString();
if (fields[i + 2].ToString().IndexOf(',') == -1)
{
CodeAssignStatement param = new CodeAssignStatement(new CodeVariableReferenceExpression(name), new CodePrimitiveExpression(fields[i + 2]));
setValues.Statements.Add(param);
}
else
{
string[] temp = fields[i + 2].ToString().Split(',');
int len = temp.Length;
if (fields[i + 1].ToString() == "Int32[]")
{
for (int j = 0; j < len; j++)
{
// Create an array indexer expression that references index 5 of array "x"
CodeArrayIndexerExpression ci1 = new CodeArrayIndexerExpression(new CodeVariableReferenceExpression(name), new CodePrimitiveExpression(j));
// Assigns the value of the 10 to the integer variable "i".
CodeAssignStatement as1 = new CodeAssignStatement(ci1, new CodePrimitiveExpression(Convert.ToInt32(temp[j].Trim())));
setValues.Statements.Add(as1);
}
}
else if (fields[i + 1].ToString() == "String[]")
{
for (int j = 0; j < len; j++)
{
CodeArrayIndexerExpression ci1 = new CodeArrayIndexerExpression(new CodeVariableReferenceExpression(name), new CodePrimitiveExpression(j));
CodeAssignStatement as1 = new CodeAssignStatement(ci1, new CodePrimitiveExpression(temp[j].Trim()));
setValues.Statements.Add(as1);
}
}
else
{
}
}
}
#endregion
compunit.Namespaces.Add(sample);
sample.Imports.Add(new CodeNamespaceImport("System"));
sample.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
sample.Imports.Add(new CodeNamespaceImport("System.ComponentModel"));
sample.Imports.Add(new CodeNamespaceImport("System.Data")); ;
sample.Imports.Add(new CodeNamespaceImport("System.Text"));
sample.Types.Add(myclass);
myclass.Members.Add(setValues);
return compunit;
}
public static void generateCode(string filenm, string fullclassname, ArrayList fields)
{
CSharpCodeProvider gen = new CSharpCodeProvider();
StreamWriter sw = new StreamWriter(filenm, false);
gen.GenerateCodeFromCompileUnit(CompileUnit(fullclassname, fields), sw, new CodeGeneratorOptions());
sw.Close();
}
//在網上找的的函數,解決了聲明變量的問題.
private static CodeVariableDeclarationStatement DeclareVariables(string dataType, string Name)
{
// 爲將要創建的變量類型創建一個CodeTypeReference對象,
// 這使得我們不必去關注該類數據在特定語言環境中的
// 與數據類型有關的細節問題。
CodeTypeReference tr = new CodeTypeReference(dataType);
// CodeVariableDeclarationStatement對象使得我們不必糾纏於
// 與特定語言有關的下列細節:在該語言的變量聲明語句中,
// 應該是數據類型在前,還是變量名稱在前;聲明變量時是
// 否要用到Dim之類的關鍵詞.
CodeVariableDeclarationStatement Declaration =
new CodeVariableDeclarationStatement(tr, Name);
// CodeObjectCreateExpression負責處理所有調用構造器的細節。
// 大多數情況下應該是new,但有時要使用New。但不管怎樣,
// 我們不必去關注這些由語言類型決定的細節.
CodeObjectCreateExpression newStatement = new
CodeObjectCreateExpression();
// 指定我們要調用其構造器的對象.
newStatement.CreateType = tr;
// 變量將通過調用其構造器的方式初始化.
Declaration.InitExpression = newStatement;
return Declaration;
}
}
}
4.再寫一個類來保存提取出來的參數;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _0331使用動態類和反射設置某個類中的變量值
{
public class programData
{
string paramName;
string paramType;
string paramValue;
string paramMSG;
public string 參數名稱
{
set;
get;
}
public string 參數類型
{
set;
get;
}
public string 參數值
{
set;
get;
}
public string 參數描述
{
set;
get;
}
}
}
準備工作基本都完成了,下面開始寫主程序了。