框架設計常需動態載入組件並呼叫其中類型,傳統做法大量使用反射,程式碼冗長且難讀。C# 4.0 引入 dynamic 關鍵字,配合 DLR(動態語言執行環境),可大幅簡化動態呼叫。
原專案依賴 Zivsoft.Log.dll,但不想強制所有專案參考此組件。改用 dynamic 後:
internal class Logger {
private static Assembly _assembly;
private static dynamic _logger; // 動態型別
static Logger() {
string dllPath = AppDomain.CurrentDomain.BaseDirectory + "Zivsoft.Log.dll";
if (File.Exists(dllPath)) {
_assembly = Assembly.LoadFile(dllPath);
try {
// 建立實例並指派給 dynamic 變數
_logger = _assembly.CreateInstance("Zivsoft.Log.Logger",
false, BindingFlags.CreateInstance, null, null, null, null);
} catch { _logger = null; }
}
}
public static void LogInfo(string msg, params object[] args) {
_logger?.LogInfo(msg, args); // 直接呼叫,編譯期不檢查
}
public static void LogWarning(string msg, params object[] args) => _logger?.LogWarning(msg, args);
public static void LogError(string msg, params object[] args) => _logger?.LogError(msg, args);
public static void LogDebug(string msg, params object[] args) => _logger?.LogDebug(msg, args);
public static void LogError(Exception ex) => LogError("{0}", ex);
}
MethodInfo.Invoke、PropertyInfo.GetValue 等反射繁瑣語法。RuntimeBinderException。Zivsoft.Log.dll,缺少組件時僅停用日誌功能,不影響主程式運行。IDispatch 呼叫。dynamic 會產生額外 DLR 呼叫站點快取,效能略低於強型別與反射(首次呼叫較慢,後續較快)。