簡體   English   中英

如何在 Powershell 中使用擴展方法?

[英]How to use Extension methods in Powershell?

我有以下代碼:

using System
public static class IntEx
{
    /// <summary>
    /// Yields a power of the given number
    /// </summary>
    /// <param name="number">The base number</param>
    /// <param name="powerOf">the power to be applied on te base number</param>
    /// <returns>Powers applied to  the base number</returns>
    public static IEnumerable<int> ListPowersOf(this int number, int powerOf)
    {
        for (var i = number; ; i <<= powerOf)
        {
            yield return i;
        }
    }
}

我已經在 Powershell(Windows 8)中加載了 dll。 我嘗試通過以下方式使用它:

$test = 1.ListPowersOf(2)

應該返回@(1, 2, 4, 8, 16...)

相反,它說沒有這樣的方法。

我嘗試了以下方法:

[BaseDllNamespace]::ListPowersOf(1,2)

依然沒有。 我在 IntEx 類中沒有命名空間。

我如何使它工作

嘗試這個:

[IntEx]::ListPowersOf(1,2)

或者

[IntEx] | gm -Static -Type Method

列出可用的靜態方法。

您還可以使用反射來獲取導出類型的列表,以查看您的類型是否可用:

[Reflection.Assembly]::LoadFile('C:path\to.dll')|select -ExpandProperty ExportedTypes

如果您真的希望它更接近點語法,您可以在IntEx類型上使用隱式或顯式轉換運算符,並將其用作 POCO 而不是靜態擴展。

它可能看起來像這樣......

$code=@'
public class MyExtClass {

    public string TheStringValue {get; set;}

    public MyExtClass(string theString){
        TheStringValue = theString;
    }

    public int NumberOf(string target)
    {
        return TheStringValue.Length - TheStringValue.Replace(target, "").Length;
    }

    public static implicit operator MyExtClass(string value){
        return new MyExtClass(value);
    }
}
'@
add-type -TypeDefinition $code

$str_eee = "TheTheThe"
$numberOfEs = ([MyExtClass]$str_eee).NumberOf("e")

if(3 -eq $numberOfEs){Write-Host PASS; exit 0}

Write-Host "FAIL";
exit 1

我意識到這在這一點上不太可能適用於 OP,但這個問題是我搜索的第一個結果,所以我會在這里發布我的想法。

我很驚訝這個還沒有被提及,但是 PowerShell 中的 CodeMethods 本質上是針對給定類型編譯的擴展方法。 它們也很容易編寫 - 特別是當您已經擁有擴展方法時。

public static class MyStringExtensions
{
    public static string Append(this string source, params char[] characters)
    {
        foreach (var c in characters)
        {
            source += c;
        }
        return source;
    }
    // named PSAppend instead of Append. This is just a naming convention I like to use,
    // but it seems some difference in name is necessary if you're adding the type data 
    // via a types.ps1xml file instead of through the Update-TypeData command
    public static string PSAppend(PSObject source, params char[] characters)
    {
        if (source.BaseObject is string sourceString)
        {
            return sourceString.Append(characters);
        }
        else throw new PSInvalidOperationException();
    }
    private static string Example() {
        var myString = "Some Value.";
        Console.WriteLine(myString.Append(" and then some more.".ToCharArray()));
        // console output: 
        // Some Value. and then some more.
    }
}

將類型定義加載到 PowerShell 后:

$method = [MyStringExtensions].GetMethod('PSAppend')
Update-TypeData -TypeName System.String -MemberName Append -MemberType CodeMethod -Value $method
# now you can use the method the same way you'd use an extension method in C#
PS:\> $myString = "Some Value."
PS:\> $myString.Append(" and then some more.")
Some value. and then some more.

代碼方法的文檔不太理想。 如果要將其構建到模塊中並在清單 (.psd1) 引用的 Types.ps1xml 文件中定義 CodeMethod,則RequiredAssemblies在清單的RequiredAssemblies中包含定義代碼方法的程序集。 (包括它作為RootModule是不夠的,因為必須在加載類型文件之前加載類型的程序集。)

以下是在 Types.ps1xml 文件中包含此類型定義的方法:

<?xml version="1.0" encoding="utf-8" ?>
<Types>
    <Type>
        <Name>System.String</Name>
        <Members>
            <CodeMethod>
                <Name>Append</Name>
                <CodeReference>
                    <TypeName>MyStringExtensions</TypeName>
                    <MethodName>PSAppend</MethodName>
                </CodeReference>
            </CodeMethod>
        </Members>
    </Type>
</Types>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM