[C#]動態設定型態
前言
有個需求,需要從設定檔中取得型態的字串與值,然後在程式中將字串轉換為指定的型態.
如果看文字描述還是不清楚的話,可以看一下下面的範例.
假設xml設定檔中有個如下的設定
<Option Type="System.Int32">88</Option>
<Option Type="System.Drawing.Color">255,255,255</Option>
現在希望程式在執行時將設定轉換為指定的型態.
思路
其實我並不常玩reflection,所以對這並不很熟,
不過以這樣的需求,大概要做得的功能如下
1.get object type from string
2.convert type – convert string type to another type
(ps.用英文寫是因為以這樣的字串在google上搜尋比較容易找到可用的資料.)
針對第一點,有個
System.Type.GetType("System.Int32");
可以取得type,不過有個問題,如果你要的type不是System下的基礎的struct的話(在Mscorlib.dll裡),
就會回傳null.
像是System.Type.GetType("System.Drawing.Color");就會回傳null.
如果要取得System.Drawing.Color的話,你必須使用完整的assembly-qualified name,如下面這樣的寫法
System.Type.GetType("System.Drawing.Color, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
(ps.我用的是framework 4.0)
但如果設定檔中要寫Assembly Qualified Name實在是太麻煩了.
所以要換個方式,從現有的assembly中撈type,再轉換.
畢竟要轉換型態也是要有載入該型態的assembly才行
而要取得載入的assembly,可以用下面的語法
Assembly[] AssembliesLoaded = AppDomain.CurrentDomain.GetAssemblies();
然後只要從這裡面撈我們要的type就可以了.到這,第一點也差不多解決了.
針對第二點.
有個TypeConvert.ConvertFromString可以處理.
TypeConverter converter = TypeDescriptor.GetConverter(typeOf(System.Int32));
return converter.ConvertFromString(inValue);
解決方案
整理一下上面的code就變成下面這個method了.
public static Object TypeConvert(string typeName, string inValue)
{
Assembly[] AssembliesLoaded = AppDomain.CurrentDomain.GetAssemblies();
Type trgType = AssembliesLoaded.Select(assembly => assembly.GetType(typeName))
.Where(type => type != null)
.FirstOrDefault();
TypeConverter converter = TypeDescriptor.GetConverter(trgType);
return converter.ConvertFromString(inValue);
}
ps.上面這個method只是一個簡單的範例,因為還沒有加上一些例外判斷.
還有也需要考慮到如果assembly未載入的話需要有動態載入的機制.
參考網頁
Type.GetType Method (String)
http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx
Show all assemblies loaded by your C# program
http://www.dijksterhuis.org/show-assemblies-loaded-program/
Convert or TryParse from string to T (generic) possible? work around?
http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/d3a139b0-9c14-400d-94f9-440b64a0122a/
How can I get System.Type from "System.Drawing.Color" string
http://stackoverflow.com/questions/944519/how-can-i-get-system-type-from-system-drawing-color-string