powershell - Powershell:如何从另一个静态方法调用静态方法
问题描述
我有一类“utils”和一些静态方法。我想从另一种方法中调用一种方法。如果我使用 $this,它会告诉我“无法在静态方法或静态属性的初始化程序中访问非静态成员 'this'。” 但是没有 $this 就找不到方法。我也不想硬编码类名 - 但如果这是唯一的解决方案,那么我必须这样做。你能在这里点亮一些灯吗?环境:Win10/Powershell 7.1 下面请找代码
class MyDateUtils
{
Static [DateTime] ToLocalTime([String]$fromDate,[String]$fromTZ, [String]$format)
{
if($fromTZ -eq $null -or $fromTZ -eq "")
{
$fromTZ = 'Eastern Standard Time'
}
$tz = [TimeZoneInfo]::FindSystemTimeZoneById($fromTZ)
$nominalDate = FormatDate($fromDate, $format)
$utcOffset = $tz.GetUtcOffset($nominalDate)
$dto = [DateTimeOffset]::new($nominalDate.Ticks, $utcOffset)
return $dto.LocalDateTime
}
Static [DateTime] FormatDate([String]$date)
{
return FormatDate($date, $null)
}
Static [DateTime] FormatDate([String]$date,[String]$format)
{
#$dateString = $date.split(' ')[0]
if($format -ne $null -and $format -ne "")
{
return [Datetime]::ParseExact( $date, $format, $null)
}
$formatList = 'MM/dd/yyyy', 'MM/dd/yyyy HH:mm:ss', 'MM/dd/yyyy HH:mm',`
'M/d/yyyy', 'M/d/yyyy HH:mm:ss', 'M/d/yyyy HH:mm',
'MM/d/yyyy', 'MM/d/yyyy HH:mm:ss', 'MM/d/yyyy HH:mm',
'M/dd/yyyy', 'M/dd/yyyy HH:mm:ss', 'M/dd/yyyy HH:mm',
'yyyy-MM-dd', 'yyyy-MM-dd HH:mm:ss', 'yyyy-MM-dd HH:mm'
$result = $null
foreach($f in $formatList)
{
try{
$result = [Datetime]::ParseExact( $date, $f, $null)
}catch {
}
if($result -ne $null)
{
return $result
}
}
return $result
}
}
然后,如果我从命令行运行以下命令,则会收到以下错误:
[MyDateUtils]::ToLocalTime('2021-02-23 07:10', $null, $null)
line |
14 | $nominalDate = FormatDate($fromDate, $format)
| ~~~~~~~~~~
| The term 'FormatDate' is not recognized as a name of a cmdlet, function, script file, or executable
| program. Check the spelling of the name, or if a path was included, verify that the path is correct
| and try again.
如果我在 FormatDate 之前添加了 $this 然后填充静态/此错误感谢您的帮助
解决方案
我不想硬编码类名 - 但如果这是唯一的解决方案,那么我必须这样做。
实际上,与 C# 不同,例如,您必须显式使用类名来引用类的静态成员,即使是在该类内部:
使用简化示例:
以下 C# 类的(近)等效项:
// C#
public class Foo {
public static string Bar() {
// Calling fellow static function Baz() requires NO qualifier.
return Baz();
}
static string Baz() {
return "baz C#";
}
}
在 PowerShell 中是以下内容:
# PowerShell
class Foo {
static [string] Bar() {
# To call the fellow static Baz() method,
# you MUST use the class name explicitly.
# Otherwise, due to PowerShell's *dynamic scoping*, PowerShell would
# look for a command named 'Baz' in the enclosing scope and its ancestors.
return [Foo]::Baz()
}
hidden static [string] Baz() {
return 'baz'
}
}
注意:Baz()
没有限定符和没有参数实际上是语法错误,但是有一个或多个参数 PowerShell 确实会Baz
在运行时查找一个命名的命令——即使使用方法(...)
语法(用分隔符括起来的参数列表,
不适用于命令——参见此答案以获取更多信息。
PowerShell总是需要一个明确的限定符来进行类内部成员访问:
$this
实例成员需要;例如,$this.PropA
需要访问声明为的实例属性[string] $PropA
,并$this.OtherMethod()
调用其他实例方法OtherMethod
。对于静态成员,表示类本身的对象,在最简单的情况下是类型文字,例如
[Foo]
,尤其是::
而不是.
,如上所示。
有关详细信息,请参阅概念about_Classes帮助主题。
虽然自动(隐式声明)$this
变量是引用类实例的方便抽象,但类本身不存在类似变量,总是导致需要在类内部重复类名,这既有点麻烦又需要维护关心。
如果-且仅当-您从实例成员引用静态成员,则可以使用以下方法解决重复类名的需要$this.GetType()
:
class Foo {
# Bar() is now an *instance* method.
[string] Bar() {
# Because $this is now defined to refer to the instance,
# you can use $this.GetType() to refer to the class.
return $this.GetType()::Baz()
}
hidden static [string] Baz() {
return 'baz'
}
}
[Foo]::new().Bar() # -> 'baz'
当然,具有类似于 的自动变量$this
会有所帮助,例如$thisType
(如果将来要支持接口$thisClass
定义,则语义上会太窄)。
如果您对拥有这样一个变量感到足够强烈,我鼓励您在 PowerShell 的 GitHub 存储库中创建一个功能请求。
笔记:
考虑到 PowerShell 的动态范围,引入新的自动变量时的一个普遍问题 是潜在的名称冲突。
类是在 PowerShell 发展的后期引入的,虽然 PowerShell 完全支持与预先存在的 .NET 类(类型)进行交互,但在 PowerShell 本身中定义它们的需求并不那么紧迫,特别是对于临时使用(使用创建的临时对象
[pscustomobject] @{ ... }
通常会这样做) )。虽然 PowerShell 的类支持永远不会赶上 C#,但正在考虑进行各种改进-请参阅GitHub 问题 #6652。
推荐阅读
- flutter - 无法在 Firestore 上保存正确的图片网址
- computer-vision - 如何在并行运行多个模型时分配 GPU 内存?
- python - pandas 如何根据逗号将单行拆分为多行并删除第三个括号和单引号?
- python - 如何更改 x 轴中的直方图标签并向直方图添加趋势线
- tcl - 带有空格的 TCL 命令解析为 Â
- python - 'NoneType' object has no attribute 'overwrites_for' discord py
- node.js - Firebase 云函数:http 函数返回 null
- android - Android convert multipart MultiBodyPart.Part into imageuri or bitmap
- api - SERVICE UNAVAILABLE error at REST API calling
- java - Is there a way to avoid N+1 queries when using a unidirectional @ManyToOne relationship in JPA + Hibernate?