2016-10-27 93 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