2013-02-15 46 views
1

我執行巴特迪斯的添加擴展方法Powershell的位置解決方案:是否可以在Powershell中使用帶有泛型類型定義的update-typedata?

http://bartdesmet.net/blogs/bart/archive/2007/09/06/extension-methods-in-windows-powershell.aspx

它的偉大工程!幾乎!他正在過濾掉泛型,但那是在黑暗時代(2007年),所以我試圖找出Powershell 3.0今天是否可能。這裏是什麼,我試圖做一個簡單的例子:

$ls = new-object collections.generic.list[string] 

'generic' 
update-typedata -force -typename collections.generic.list`1 ` 
    -membertype scriptmethod -membername test -value {'test!'} 

$ls.test() # fail 

'string' 
update-typedata -force -typename collections.generic.list[string] ` 
    -membertype scriptmethod -membername test -value {'test!'} 

$ls.test() # works! 

此輸出:

generic 
Method invocation failed because [System.Collections.Generic.List`1[[System.String, mscorlib, 
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]] doesn't contain a method 
named 'test'. 
At C:\Temp\blah5.ps1:12 char:1 
+ $ls.test() 
+ ~~~~~~~~~~ 
    + CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
    + FullyQualifiedErrorId : MethodNotFound 

string 
test! 

現在,PowerShell是能夠與泛型類型定義工作。它似乎沒有與類型數據系統集成...

或者我做錯了嗎?有什麼辦法可以讓你做這項工作?

回答

2

自定義類型擴展取決於$object.PSTypeNames - 無論您看到PowerShell在決定給定擴展名是否適用於某個類型時都會使用它。

在你的第一個例子中,你是「掛鉤」的方法來鍵入可能不會在任何對象的PSTypeNames顯示:

$ls.PSTypeNames 
System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] 
System.Object 

顯然,連接方法應與任何通用的系統中使用。對象是矯枉過正的(至少可以這麼說)。你可以解決它通過創建具有一些特殊功能的仿製藥,這將包裹新物體+添加了一些PSTypeNames:

Update-TypeData -Force -TypeName System.Collections.Generic.List -Value { 
    'Works!' 
} -MemberName Test -MemberType ScriptMethod 

function New-GenericObject { 
param (
    [Parameter(Mandatory)] 
    $TypeName 
) 
    $out = New-Object @PSBoundParameters 
    $out.PSTypeNames.Insert(
     0, 
     ($out.GetType().FullName -split '`')[0] 
    ) 
    , $out 
} 

$ls = New-GenericObject -TypeName Collections.Generic.List[string] 
$ls.Test() 

這更是一個比草圖實際執行的...我想真正的代理功能會比簡單的包裝要好得多。

相關問題