作爲一個初學者,整了一下午才弄明白,在這裏寫出來分享給像我一樣的初學者
C#的Assembly.Load.CreateInstance是C#反射機制的一部分因爲論壇上有個人問了個類似的問題,然後之前看設計模式上還提到了這個,當時沒弄明白而且還可恥的誤導了。。。
C#的Assembly.Load.CreateInstance方法的使用是這樣的:
Assembly.Load("程序集名稱").CreateInstance("命名空間.類")
然後他會返回一個object類型(也就是所有類的基類)的一個對象,這時候我們使用強制類型轉換就行了
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;//使用反射一定要加上這個!
namespace Reflection
{
class Program
{
static void Main(string[] args)
{
ILoveMM mm = (ILoveMM)Assembly.Load("Reflection").CreateInstance("Reflection.LoveMM");//這塊直接強制類型轉換就行
mm.Output();
}
}
interface ILoveMM
{
void Output();
}
class LoveMM : ILoveMM
{
public void Output()
{
Console.WriteLine("I love you MM");
}
}
}
這裏面要說一點,假如有一個類是在另外的一個類裏面的話,比如在上面的程序中,Program類中還有一個MM類的話,那麼我們用“Reflection.Program.MM”去使用方法的話是不可行的,這樣方法會返回null,如果哪位大牛知道這種情況應該怎麼寫,請不吝賜教~ :)
上面的程序有一個缺點就是如果我們想要生成另外的一個類的對象的話要麼改代碼,要麼輸入,貌似有點違背開閉原則?所以我們可以用config文件來改變這一個現狀。
添加config文件:
在“項目”->“添加新項” 中找到“應用程序配置文件”,然後點確定,這樣我們的config文件就誕生啦~
這個文件我是這麼寫的。。。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ClassName" value="LoveMM1" />
</appSettings>
</configuration>
這裏面的key後面的"ClassName"就是我們要保存的變量名稱(因爲不知道怎麼叫T_T) value也就是“LoveMM1”是要保存的值
注意"appSettings"的大小寫一定不要錯,不過vs的代碼補全可以彌補這點~
然後就是config文件的讀寫問題
對於config文件的讀寫多是用ConfigurationManager,這個類的使用方法嘛。。。
首先在“項目”->“添加引用” 中找到System.Configuration 然後點擊這項,會發現前面出來一個√ 然後確定。
接着在代碼揩油加上 using System.Configuration; 就可以用了,直接加 using貌似不能用 -_-||
現在我們就能使用ConfigurationManager類啦~
讀取的方法就是
string s = ConfigurationManager.AppSettings["ClassName"].ToString();//這裏面的ClassName對應上面App.config文件中的 key
這樣我們就能讀取到config文件中所保存的相關信息。
修改來說相對麻煩
Configuration ConfigWriter = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);//新建寫config文件的對象
ConfigWriter.AppSettings.Settings["ClassName"].Value = "LoveMM2";//ClassName是要改的key LoveMM2是要修改的值
ConfigWriter.Save(ConfigurationSaveMode.Modified);//保存文件
//ConfigWriter.SaveAs("App.config");
ConfigurationManager.RefreshSection("appSettings");//刷新appSettings
再詳細的說一下
第一行就是打開config文件 ConfigurationUserLevel.None是獲取所有用戶的Configuration
第二行,這個一開始以爲是方法,後來發現不是-_-|| 就是["key"].value的方式
第三行,可能有人已經發現了,第四行被我註釋掉了,因爲一開始我也是用第四行的方法保存的,但是發現保存時保存了,結果仍然不變,所以就按MSDN的方式去寫了。
最後一行,這個玩意也挺重要的。。。這個就是負責刷新,要不然保存config文件,然後再讀取,結果發現數值不變-_-||
最後上下代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Configuration;
namespace Reflection
{
class Program
{
public static void ReadConfig()
{
string s = ConfigurationManager.AppSettings["ClassName"].ToString();
string NameSpaceName = "Reflection";
string ClassName = NameSpaceName + "." + s;
ILoveMM mm = (ILoveMM)Assembly.Load(NameSpaceName).CreateInstance(ClassName);
mm.Output();
}
public static void WriteConfig()
{
Configuration ConfigWriter = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigWriter.AppSettings.Settings["ClassName"].Value = "LoveMM2";
ConfigWriter.Save(ConfigurationSaveMode.Modified);
//ConfigWriter.SaveAs("App.config");
ConfigurationManager.RefreshSection("appSettings");
}
static void Main(string[] args)
{
ReadConfig();
WriteConfig();
ReadConfig();
Console.Read();
}
}
interface ILoveMM
{
void Output();
}
class LoveMM1 : ILoveMM
{
public void Output()
{
Console.WriteLine("I love you MM");
}
}
class LoveMM2 : ILoveMM
{
public void Output()
{
Console.WriteLine("5211314");
}
}
}
最後的輸出就是
I love you MM
5211314
成功~