diff --git a/src/System.Management.Automation/engine/lang/scriptblock.cs b/src/System.Management.Automation/engine/lang/scriptblock.cs index 8a16a5f8726..77b3affb440 100644 --- a/src/System.Management.Automation/engine/lang/scriptblock.cs +++ b/src/System.Management.Automation/engine/lang/scriptblock.cs @@ -647,16 +647,17 @@ internal ReadOnlyCollection OutputType /// /// This does normal array reduction in the case of a one-element array. /// - internal static object GetRawResult(List result) + internal static object GetRawResult(List result, bool wrapToPSObject) { switch (result.Count) { case 0: return AutomationNull.Value; case 1: - return LanguagePrimitives.AsPSObjectOrNull(result[0]); + return wrapToPSObject ? LanguagePrimitives.AsPSObjectOrNull(result[0]) : result[0]; default: - return LanguagePrimitives.AsPSObjectOrNull(result.ToArray()); + object resultArray = result.ToArray(); + return wrapToPSObject ? LanguagePrimitives.AsPSObjectOrNull(resultArray) : resultArray; } } @@ -807,7 +808,7 @@ internal object InvokeAsDelegateHelper(object dollarUnder, object dollarThis, ob outputPipe: outputPipe, invocationInfo: null, args: args); - return GetRawResult(rawResult); + return GetRawResult(rawResult, wrapToPSObject: false); } #endregion @@ -934,7 +935,7 @@ internal object DoInvokeReturnAsIs( outputPipe: outputPipe, invocationInfo: null, args: args); - return GetRawResult(result); + return GetRawResult(result, wrapToPSObject: true); } internal void InvokeWithPipe( diff --git a/test/powershell/engine/Api/LanguagePrimitive.Tests.ps1 b/test/powershell/engine/Api/LanguagePrimitive.Tests.ps1 index f4c3a5975cc..6f0c85fc4e1 100644 --- a/test/powershell/engine/Api/LanguagePrimitive.Tests.ps1 +++ b/test/powershell/engine/Api/LanguagePrimitive.Tests.ps1 @@ -102,4 +102,54 @@ Describe "Language Primitive Tests" -Tags "CI" { $val | Should -BeTrue $result | Should -BeExactly $compareResult } + + It "Convert ScriptBlock to delegate type" { + $code = @' + using System; + namespace Test.API + { + public enum TestEnum + { + Music, + Video + } + public class LanguagePrimitivesTest + { + Func _handlerReturnObject; + Func _handlerReturnEnum; + public LanguagePrimitivesTest(Func handlerReturnObject, Func handlerReturnEnum) + { + _handlerReturnObject = handlerReturnObject; + _handlerReturnEnum = handlerReturnEnum; + } + + public bool TestHandlerReturnEnum() + { + var value = _handlerReturnEnum("bar"); + return value == TestEnum.Music; + } + + public bool TestHandlerReturnObject() + { + object value = _handlerReturnObject("bar"); + return value is TestEnum; + } + } + } +'@ + + if (-not ("Test.API.TestEnum" -as [type])) + { + Add-Type -TypeDefinition $code + } + + # The script actually returns a enum value, and the converted delegate should return the boxed enum value. + $handlerReturnObject = [System.Func[string, object]] { param([string]$str) [Test.API.TestEnum]::Music } + # The script actually returns a string, and the converted delegate should return the corresponding enum value. + $handlerReturnEnum = [System.Func[string, Test.API.TestEnum]] { param([string]$str) "Music" } + $test = [Test.API.LanguagePrimitivesTest]::new($handlerReturnObject, $handlerReturnEnum) + + $test.TestHandlerReturnEnum() | Should -BeTrue + $test.TestHandlerReturnObject() | Should -BeTrue + } }