日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

C#强化系列文章五:动态代码的使用(反射和动态生成类)

發(fā)布時(shí)間:2025/1/21 102 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#强化系列文章五:动态代码的使用(反射和动态生成类) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在軟件開(kāi)發(fā)尤其是框架和底層開(kāi)發(fā)時(shí),為了更靈活的控制代碼,常常需要進(jìn)行一些動(dòng)態(tài)的操作。比如根據(jù)用戶的輸入等動(dòng)態(tài)的調(diào)用類中的方法或者根據(jù)數(shù)據(jù)庫(kù)表結(jié)構(gòu)、用戶要求動(dòng)態(tài)的生成一些類,然后再動(dòng)態(tài)的調(diào)用類中的方法。當(dāng)然使用這些方式時(shí)會(huì)對(duì)性能有一點(diǎn)影響,具體使用過(guò)程中可以根據(jù)實(shí)際情況來(lái)定,不過(guò)一般的B/S開(kāi)發(fā)中主要的瓶頸還是在數(shù)據(jù)庫(kù)操作和網(wǎng)速方面,這點(diǎn)影響應(yīng)該可以忽略的
下面我就從這兩個(gè)方面來(lái)說(shuō)說(shuō)動(dòng)態(tài)代碼的使用:
一、反射的使用
可以使用反射動(dòng)態(tài)地創(chuàng)建類型的實(shí)例,將類型綁定到現(xiàn)有對(duì)象,或從現(xiàn)有對(duì)象中獲取類型。然后,可以調(diào)用類型的方法或訪問(wèn)其字段和屬性。
需要使用的命名空間:System.Reflection
反射的作用很多,下面的例子主要是看一下怎么動(dòng)態(tài)的調(diào)用類中的方法。
例子類
????class?ReflTest1
????
{
????????
private?string?_prop1;

????????
public?string?Prop1
????????
{
????????????
get?{?return?_prop1;?}
????????????
set?{?_prop1?=?value;?}
????????}

????
????????
public?void?Write1(string?strText)
????????
{
????????????Console.WriteLine(
"111111111:"?+?strText);
????????}

????????
public?void?Write2(string?strText)
????????
{
????????????Console.WriteLine(
"222222222:"?+?strText);
????????}

????????
public?void?MyWrite(string?strText)
????????
{
????????????Console.WriteLine(
"3333333333:"?+?strText);
????????}

????}

這個(gè)例子中提供了三個(gè)方法和一個(gè)屬性,下面的代碼來(lái)動(dòng)態(tài)的調(diào)用它們:
????????????string?strText?=?"abcd";

????????????BindingFlags?flags?
=?(BindingFlags.NonPublic?|?BindingFlags.Public?|
????????????????BindingFlags.Static?
|?BindingFlags.Instance?|?BindingFlags.DeclaredOnly);

????????????Type?t?
=?typeof(ReflTest1);
????????????MethodInfo[]?mi?
=?t.GetMethods(flags);
????????????Object?obj?
=?Activator.CreateInstance(t);

????????????
foreach?(MethodInfo?m?in?mi)
????????????
{
????????????????
if?(m.Name.StartsWith("Write"))
????????????????
{
????????????????????m.Invoke(obj,?
new?object[]?{?strText?});
????????????????}

????????????}


????????????MethodInfo?mMy?
=?t.GetMethod("MyWrite");
????????????
if?(mMy?!=?null)
????????????
{
????????????????mMy.Invoke(obj,?
new?object[]?{?strText?});
????????????}

BindingFlags用來(lái)設(shè)置要取得哪些類型的方法,然后我們就可以取得這些方法來(lái)動(dòng)態(tài)的調(diào)用。(當(dāng)然為了可以循環(huán)的調(diào)用方法,在方法的命名方面可以自己指定一個(gè)規(guī)則)

二、動(dòng)態(tài)生成類
我們可以在程序運(yùn)行過(guò)程中調(diào)用.NET中提供的編譯類,動(dòng)態(tài)的將一段string編譯成一個(gè)類,然后再通過(guò)反射來(lái)調(diào)用它
需要使用的命名空間:System.CodeDom System.CodeDom.Compiler Microsoft.CSharp System.Reflection
動(dòng)態(tài)創(chuàng)建、編譯類的代碼如下:
????????public?static?Assembly?NewAssembly()
????????
{
????????????
//創(chuàng)建編譯器實(shí)例。???
????????????provider?=?new?CSharpCodeProvider();
????????????
//設(shè)置編譯參數(shù)。???
????????????paras?=?new?CompilerParameters();
????????????paras.GenerateExecutable?
=?false;
????????????paras.GenerateInMemory?
=?true;

????????????
//創(chuàng)建動(dòng)態(tài)代碼。???
????????????StringBuilder?classSource?=?new?StringBuilder();
????????????classSource.Append(
"public???class???DynamicClass?\n");
????????????classSource.Append(
"{\n");

????????????
//創(chuàng)建屬性。???
????????????classSource.Append(propertyString("aaa"));
????????????classSource.Append(propertyString(
"bbb"));
????????????classSource.Append(propertyString(
"ccc"));

????????????classSource.Append(
"}");

????????????System.Diagnostics.Debug.WriteLine(classSource.ToString());

????????????
//編譯代碼。???
????????????CompilerResults?result?=?provider.CompileAssemblyFromSource(paras,?classSource.ToString());

????????????
//獲取編譯后的程序集。???
????????????Assembly?assembly?=?result.CompiledAssembly;

????????????
return?assembly;
????????}


????????
private?static?string?propertyString(string?propertyName)
????????
{
????????????StringBuilder?sbProperty?
=?new?StringBuilder();
????????????sbProperty.Append(
"?private???int???_"?+?propertyName?+?"???=???0;\n");
????????????sbProperty.Append(
"?public???int???"?+?""?+?propertyName?+?"\n");
????????????sbProperty.Append(
"?{\n");
????????????sbProperty.Append(
"?get{???return???_"?+?propertyName?+?";}???\n");
????????????sbProperty.Append(
"?set{???_"?+?propertyName?+?"???=???value;???}\n");
????????????sbProperty.Append(
"?}");
????????????
return?sbProperty.ToString();
????????}
propertyString方法就是用來(lái)拼寫字符串的
整個(gè)代碼比較簡(jiǎn)單,主要步驟就是:1、拼寫類的字符串? 2、調(diào)用CSharpCodeProvider類進(jìn)行編譯得到程序集(assembly)

接下來(lái)就可以利用之前反射的方法來(lái)動(dòng)態(tài)調(diào)用這個(gè)類中的屬性了:
????????????Assembly?assembly?=?NewAssembly();

????????????
object?Class1?=?assembly.CreateInstance("DynamicClass");
????????????ReflectionSetProperty(Class1,?
"aaa",?10);
????????????ReflectionGetProperty(Class1,?
"aaa");

????????????
object?Class2?=?assembly.CreateInstance("DynamicClass");
????????????ReflectionSetProperty(Class1,?
"bbb",?20);
????????????ReflectionGetProperty(Class1,?
"bbb");
DynamicClass是我動(dòng)態(tài)類的類名,aaa和bbb是其中的屬性
ReflectionSetProperty和ReflectionGetProperty代碼如下:
給屬性賦值
????????private?static?void?ReflectionSetProperty(object?objClass,?string?propertyName,?int?value)
????????
{
????????????PropertyInfo[]?infos?
=?objClass.GetType().GetProperties();
????????????
foreach?(PropertyInfo?info?in?infos)
????????????
{
????????????????
if?(info.Name?==?propertyName?&&?info.CanWrite)
????????????????
{
????????????????????info.SetValue(objClass,?value,?
null);
????????????????}

????????????}

????????}

取得屬性的值
????????private?static?void?ReflectionGetProperty(object?objClass,?string?propertyName)
????????
{
????????????PropertyInfo[]?infos?
=?objClass.GetType().GetProperties();
????????????
foreach?(PropertyInfo?info?in?infos)
????????????
{
????????????????
if?(info.Name?==?propertyName?&&?info.CanRead)
????????????????
{
????????????????????System.Console.WriteLine(info.GetValue(objClass,?
null));
????????????????}

????????????}

????????}


總結(jié)

以上是生活随笔為你收集整理的C#强化系列文章五:动态代码的使用(反射和动态生成类)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。