mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Do not wrap return result to PSObject when converting ScriptBlock to delegate (#10619)
This is a breaking change for the delegate types with the object return type: Before this change, the returned object will always be an PSObject instance. After this change, the returned object is the underlying object, which could still be an PSObject if that's what the script actually returns.
This commit is contained in:
@@ -647,16 +647,17 @@ namespace System.Management.Automation
|
||||
/// <remarks>
|
||||
/// This does normal array reduction in the case of a one-element array.
|
||||
/// </remarks>
|
||||
internal static object GetRawResult(List<object> result)
|
||||
internal static object GetRawResult(List<object> 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 @@ namespace System.Management.Automation
|
||||
outputPipe: outputPipe,
|
||||
invocationInfo: null,
|
||||
args: args);
|
||||
return GetRawResult(rawResult);
|
||||
return GetRawResult(rawResult, wrapToPSObject: false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -934,7 +935,7 @@ namespace System.Management.Automation
|
||||
outputPipe: outputPipe,
|
||||
invocationInfo: null,
|
||||
args: args);
|
||||
return GetRawResult(result);
|
||||
return GetRawResult(result, wrapToPSObject: true);
|
||||
}
|
||||
|
||||
internal void InvokeWithPipe(
|
||||
|
||||
@@ -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<string, object> _handlerReturnObject;
|
||||
Func<string, TestEnum> _handlerReturnEnum;
|
||||
public LanguagePrimitivesTest(Func<string, object> handlerReturnObject, Func<string, TestEnum> 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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user