2016-10-27 50 views
1

试图建立一个功能类似如下:PowerShell的功能限制数据类型

Function Get-SqlErrorLogPrevious24 { 
    [CmdletBinding()] 
    Param (
     [Parameter(Mandatory=$True,Position=1)] 
     [Microsoft.SqlServer.Management.Smo.Server]$Server 
    ) 

    ($Server.ReadErrorLog()).where{$_.logdate -ge ((Get-Date).AddHours(-24))} 
} 

什么我虽然注意到了,就是我可以在短短的字符串传递,而不是服务器对象。

有没有办法在Powershell中强制执行传入的数据类型,还是总是隐式地将字符串转换为SMO对象?

回答

3

不.PowerShell有几个“策略”,它用来确保您在函数中接收到的是正确的类型。如果它可以使用其中的一个将传递的值(在这种情况下是一个字符串)转换为所需的类型(一个SMO对象),它会这样做。

这里是一个great post which lists 10 different strategies.

  1. 直接分配。如果您的输入可直接分配,只需将您的输入转换为该类型即可。
  2. 基于语言的转换。这些基于语言的转换是在目标类型为void,Boolean,String,Array,Hashtable,PSReference(即:[ref]),XmlDocument(即:[xml]))时完成的。委托(以支持ScriptBlock来委派转换)和Enum。
  3. 解析转换。如果目标类型定义了一个接受该输入的Parse()方法,请使用该方法。
  4. 静态创建转换。如果目标类型定义了一个接受该输入的static :: Create()方法,请使用该方法。
  5. 构造函数转换。如果目标类型定义了一个接受输入的构造函数,请使用它。
  6. 投射转换。如果目标类型从源类型定义隐式或显式转换运算符,请使用该运算符。如果源类型为目标类型定义了隐式或显式的转换运算符,请使用该运算符。
  7. IC转换。如果源类型定义了知道如何转换为目标类型的IConvertible实现,请使用该类型。
  8. IDictionary转换。如果源类型是IDictionary(即:Hashtable),则尝试使用其默认构造函数创建目标类型的实例,然后使用IDictionary中的名称和值设置源对象的属性。
  9. PSObject属性转换。如果源类型是PSObject,请尝试使用其默认构造函数创建目标类型的实例,然后使用PSObject中的属性名称和值设置源对象上的属性。 。如果名称映射到方法而不是属性,请使用该值作为其参数来调用该方法。
  10. TypeConverter转换。如果存在可以处理转换的已注册TypeConverter或PSTypeConverter,请执行此操作。您可以通过types.ps1xml文件(请参阅:$ pshome \ Types.ps1xml)或通过Update-TypeData注册TypeConverter。
4

您可以实现自定义转换属性,它会抛出异常,如果类型是不同的:

Add-Type @' 
    using System; 
    using System.Management.Automation; 
    public class EnforceTypeAttribute : ArgumentTransformationAttribute { 
     private Type type; 
     public EnforceTypeAttribute(Type type) { 
      this.type=type; 
     } 
     public override object Transform(EngineIntrinsics engineIntrinsics, object inputData) { 
      if(type.IsInstanceOfType(inputData)) { 
       return inputData; 
      } else { 
       throw new Exception("Incorrect type."); 
      } 
     } 
    } 
'@ 

function f {param([int]$i) $i} 
function g {param([EnforceType([int])][int]$i) $i} 

f 1 #OK 
f '1' #OK 
g 1 #OK 
g '1' #Error