问题
I have the following code:
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;
}
}
}
I've loaded the dll in Powershell(Windows 8). I try to use it the following way:
$test = 1.ListPowersOf(2)
Should return @(1, 2, 4, 8, 16...)
Instead it says there is no such method.
I tried the following:
[BaseDllNamespace]::ListPowersOf(1,2)
Still nothing. I have no namespace in the IntEx class.
How do I make it work
回答1:
Try this:
[IntEx]::ListPowersOf(1,2)
or
[IntEx] | gm -Static -Type Method
to list available static methods.
You can also use reflection to obtain list of exported types to see if yours is available:
[Reflection.Assembly]::LoadFile('C:path\to.dll')|select -ExpandProperty ExportedTypes
回答2:
If you really want it to read closer to dot syntax, you could use an implicit or explicit conversion operator on your IntEx
type and use it as a POCO instead of as a static extension.
It might look something like this...
$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
回答3:
I realize this isn't likely to apply to OP at this point, but this question was the first result for my search so I'll post what I figured out here.
I'm pretty surprised this one isn't already mentioned, but CodeMethods in PowerShell are essentially compiled extension methods for a given type. They're pretty easy to write, too - especially when you already have the extension method.
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.
}
}
After loading the type definition into 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.
Documentation for code methods is less than ideal. If you're building this into a module and defining a CodeMethod in your Types.ps1xml file referenced by your manifest (.psd1), you'll need to include the assembly that defines the code method in the RequiredAssemblies
of the manifest. (Including it as RootModule
is insufficient because the assemblies of the type(s) must be loaded before the type file(s) are loaded.)
Here's how you'd include this type definition in a Types.ps1xml file:
<?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>
来源:https://stackoverflow.com/questions/25915450/how-to-use-extension-methods-in-powershell