快速背景:我是PowerShell的新手,但我是一个精通C#开发者。到目前为止,我对PowerShell的看法很复杂。我爱它有一天,恨它。就在我认为我已经弄明白的时候,我被困了好几个小时试验并且错误一些我认为应该实现的功能但是没有。
我希望PowerShell让我覆盖一个对象的ToString()方法(它所做的),这样当一个对象在双引号字符串中被引用时,它将调用我的自定义ToString方法(它没有)。
示例:
PS C:\> [System.Text.Encoding] | Update-TypeData -Force -MemberType ScriptMethod -MemberName ToString -Value { $this.WebName }
PS C:\> $enc = [System.Text.Encoding]::ASCII
PS C:\> $enc.ToString() ### This works as expected
us-ascii
PS C:\> "$enc" ### This calls the object's original ToString() method.
System.Text.ASCIIEncoding
如何定义.NET对象的变量扩展行为?
答案 0 :(得分:1)
语言规范没有提及覆盖变量替换的任何内容,因此我认为没有一种确定的方法可以完全按照您的要求进行操作。如果涉及单个类,您可以在C#中对其进行子类化,但对于类层次结构,我能想到的最接近的是在对象周围生成一个具有所需行为的包装器。
$source = @"
using System.Text;
public class MyEncoding
{
public System.Text.Encoding encoding;
public MyEncoding()
{
this.encoding = System.Text.Encoding.ASCII;
}
public MyEncoding(System.Text.Encoding enc)
{
this.encoding = enc;
}
public override string ToString() { return this.encoding.WebName; }
}
"@
Add-Type -TypeDefinition $Source
然后你可以像这样使用它:
PS C:\scripts> $enc = [MyEncoding][System.Text.Encoding]::ASCII;
PS C:\scripts> "$enc"
us-ascii
PS C:\scripts> $enc = [MyEncoding][System.Text.Encoding]::UTF8;
PS C:\scripts> "$enc"
utf-8
PS C:\scripts> $enc.encoding
BodyName : utf-8
EncodingName : Unicode (UTF-8)
HeaderName : utf-8
WebName : utf-8
WindowsCodePage : 1200
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
IsSingleByte : False
EncoderFallback : System.Text.EncoderReplacementFallback
DecoderFallback : System.Text.DecoderReplacementFallback
IsReadOnly : True
CodePage : 65001
如果您不喜欢额外的.encoding
来获取底层对象,您可以将所需的属性添加到包装器中。
答案 1 :(得分:1)
我偶然发现了一个半解决方案,并在Powershell中发现了另一个奇怪的行为。看来,当字符串扩展涉及集合时,将调用ToString()方法的用户定义的ScriptMethod定义,而不是对象的原始ToString()方法。
所以,使用上面的例子,所有必要的是添加一个糟糕的逗号:
PS C:\> [System.Text.Encoding] | Update-TypeData -Force -MemberType ScriptMethod -MemberName ToString -Value { $this.WebName }
PS C:\> $enc = ,[System.Text.Encoding]::ASCII # The unary comma operator creates an array
PS C:\> "$enc" ### This now works
us-ascii
这对我来说似乎是个错误。