简体   繁体   English

Get-Date 转换为字符串 vs ToString()

[英]Get-Date cast to string vs ToString()

My understanding of PowerShell's string embedding syntax "$($object)" has always been that $object is cast to [System.String] , which invokes $object.ToString() .我对 PowerShell 的字符串嵌入语法"$($object)"理解一直是$object被强制转换为[System.String] ,它调用$object.ToString() However, I've noticed this curious behavior with the [DateTime] class using PowerShell 4.0 on Windows 8.1.但是,我注意到在 Windows 8.1 上使用 PowerShell 4.0 的[DateTime]类的这种奇怪行为。

PS> $x = Get-Date

PS> $x.GetType() | select -ExpandProperty Name
DateTime

PS> $x.ToString()
2015-05-29 13:36:06

PS> [String]$x
05/29/2015 13:36:06

PS> "$($x)"
05/29/2015 13:36:06

It seems that "$($object)" gives the same behavior as casting to string, but is clearly producing a different result from $object.ToString() .似乎"$($object)"提供了与转换为字符串相同的行为,但显然产生了与$object.ToString()不同的结果。 $x.ToString() is consistent with the short date format set in intl.cpl (yyyy-MM-dd). $x.ToString()与 intl.cpl (yyyy-MM-dd) 中设置的短日期格式一致。 [String]$x appears to use the en-US default. [String]$x似乎使用 en-US 默认值。

It is possible this is simply a bug in the DateTime class, but I'm more surprised that the different methods of converting an object to a string produce different results.这可能只是 DateTime 类中的一个错误,但我更惊讶的是将对象转换为字符串的不同方法会产生不同的结果。 What are the rules for casting an object to a string, if not calling ToString() ?如果不调用ToString() ,将对象转换为字符串的规则是什么? Is the DateTime class simply a special case because of its overloading of ToString(String) ? DateTime 类是否只是一个特例,因为它重载了ToString(String)

If an object implements the IFormattable interface, then PowerShell will call IFormattable.ToString instead of Object.ToString for the cast operation.如果一个对象实现了IFormattable接口,那么PowerShell的将调用IFormattable.ToString而不是Object.ToString的转换操作。 A similar thing happens for static Parse method: if there is an overload with IFormatProvider parameter, then it would be called.静态Parse方法也会发生类似的事情:如果IFormatProvider参数存在重载,则将调用它。

Add-Type -TypeDefinition @'
    using System;
    using System.Globalization;
    public class MyClass:IFormattable {
        public static MyClass Parse(string str) {
            return new MyClass{String=str};
        }
        public static MyClass Parse(string str,IFormatProvider fp) {
            return new MyClass{String=str,FormatProvider=((CultureInfo)fp).DisplayName};
        }
        public string String {get;private set;}
        public string FormatProvider {get;private set;}
        public override string ToString() {
            return "Object.ToString()";
        }
        string IFormattable.ToString(string format,IFormatProvider fp) {
            return string.Format("IFormattable.ToString({0},{1})",format,((CultureInfo)fp).DisplayName);
        }
    }
'@
[String](New-Object MyClass) #Call IFormattable.ToString(null,CultureInfo.InvariantCulture)
[MyClass]'Test'              #Call MyClass.Parse("Test",CultureInfo.InvariantCulture)

Your question is not PowerShell question, but a .NET question.您的问题不是 PowerShell 问题,而是 .NET 问题。 PowerShell scripts can use the .NET structure [datetime] as it is, ie, PowerShell does not change its behavior. PowerShell 脚本可以按原样使用 .NET 结构 [datetime],即 PowerShell 不会改变其行为。

What are the rules for casting an object to a string, if not calling ToString()?如果不调用 ToString(),将对象转换为字符串的规则是什么?

Casting uses culture invariant definitions.强制转换使用文化不变定义。 The ToString() method can contain culture dependent implementations, because it is overridable . ToString()方法可以包含文化相关的实现,因为它是可覆盖的

Is the DateTime class simply a special case because of its overloading of ToString(String)? DateTime 类是否只是一个特例,因为它重载了 ToString(String)?

First, DateTime is not a class;首先,DateTime 不是一个类; it's a structure.这是一个结构。 Second, there's no ToString() method overloading;其次,没有ToString()方法重载; in this case , the correct denomination is overriding (it is overriding the Object.ToString() method).在这种情况下,正确的面额是覆盖(覆盖Object.ToString()方法)。

To understand better what I'm meaning, have fun with these pretty funny date and time printing in different cultures (copy, paste and run):为了更好地理解我的意思,享受这些在不同文化中打印的非常有趣的日期和时间(复制、粘贴和运行):

function f{
    $x=get-date
    [CultureInfo]$currentCulture = [System.Threading.Thread]::CurrentThread.CurrentCulture
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('en-US')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('ar-IQ')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('de-DE')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('ru-RU')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('fr-FR')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('zh-CN')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('zh-HK')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('zh-TW')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('hu-HU')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('ko-KR')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('ja-JP')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('ka-GE')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=[CultureInfo]::CreateSpecificCulture('pt-BR')
    $x.ToString()
    [System.Threading.Thread]::CurrentThread.CurrentCulture=$currentCulture
}

f

Notice that the code above will produce different printing if run either in ISE or in non-ISE versions of PowerShell.请注意,如果在 ISE 或非 ISE 版本的 PowerShell 中运行,上面的代码将产生不同的打印

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM