在開發基於 Flash AMF 協議的應用時,開發者常面臨一個棘手的問題:如何將 ActionScript 的 ASObject 高效轉換為 .NET 的強類型類別。以《熱血三國》遊戲中的戰場資訊為例,伺服器回傳的 AMF 資料結構複雜,若逐欄位手動映射不僅繁瑣,更極易出錯。
AutoParseASObject<T> 類別正是為了解決此痛點而生。其核心原理利用 .NET 反射機制:根據泛型類型 T 動態創建實例,遍歷目標類別的所有公開欄位與屬性,再從 ASObject 的鍵值對中尋找同名鍵(忽略大小寫),最後透過 Convert.ChangeType 完成型別轉換並賦值。
public class AutoParseASObject<T>
{
public static T Parse(ASObject pObj)
{
try
{
Type tmpType = typeof(T);
T tmpRstObj = (T)Activator.CreateInstance(tmpType);
MemberInfo[] tmpMembers = tmpType.GetMembers();
for (int i = 0; i < tmpMembers.Length; i++)
{
var tmpVar = from value in pObj
where value.Key.ToLower() == tmpMembers[i].Name.ToLower()
select value.Value;
using (IEnumerator<object> tmpEnum = tmpVar.GetEnumerator())
if (tmpEnum.MoveNext())
{
switch (tmpMembers[i].MemberType)
{
case MemberTypes.Field:
tmpType.GetField(tmpMembers[i].Name)
.SetValue(tmpRstObj, Convert.ChangeType(tmpEnum.Current,
tmpType.GetField(tmpMembers[i].Name).FieldType));
break;
case MemberTypes.Property:
if (tmpType.GetProperty(tmpMembers[i].Name).CanWrite)
tmpType.GetProperty(tmpMembers[i].Name)
.SetValue(tmpRstObj, Convert.ChangeType(tmpEnum.Current,
tmpType.GetProperty(tmpMembers[i].Name).PropertyType), null);
break;
}
}
}
return tmpRstObj;
}
catch { return default(T); }
}
}
此基礎類不僅限於 AMF 協議,同樣適用於資料庫實體映射、JSON 反序列化等場景。開發者只需確保目標類別的欄位/屬性名稱與資料來源鍵名一致,即可實現零配置自動映射。若需支援更複雜的型別轉換(如巢狀物件、集合),可在衍生類中覆寫邏輯或引入 Attribute 標記進一步增強靈活性。
文中提到利用 System.CodeDom 或 Roslyn 進行動態編譯,可根據資料結構即時生成對應的 .NET 類別,省去手動定義實體的步驟。這在處理結構頻繁變動的外部 API 時極具價值,是架構演進的自然方向。