C# 擴充方法本質是靜態方法,編譯器透過 this 參數語法糖讓實例呼叫。但 IronPython 執行引擎 (DLR) 無法自動發現這類方法,直接呼叫會拋出 AttributeError。
在組件層級套用 [ExtensionTypeAttribute],告知 DLR 哪個類型擴充了哪個目標類型:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
public sealed class ExtensionTypeAttribute : Attribute {
private readonly Type _extends; // 被擴充的目標類型
private readonly Type _extensionType; // 實作擴充方法的靜態類別
public ExtensionTypeAttribute(Type extends, Type extensionType) {
if (extends == null) throw new ArgumentNullException(nameof(extends));
if (extensionType != null && !extensionType.IsPublic && !extensionType.IsNestedPublic)
throw new ArgumentException("擴充類別必須為 public");
_extends = extends;
_extensionType = extensionType;
}
public Type Extends => _extends;
public Type ExtensionType => _extensionType;
}
[assembly: ExtensionTypeAttribute(typeof(string), typeof(MyStringExtensions))]
// 宣告 string 被 MyStringExtensions 擴充
public static class MyStringExtensions {
public static string Foo(this string s) => "Extended: " + s;
}
IronPython 即可透過 import MyAssembly 後直接呼叫 "abc".Foo()。