From 5d5dd197c6abaa48afe1e79c0c07ea4812a02ce0 Mon Sep 17 00:00:00 2001 From: neuecc Date: Fri, 19 Sep 2025 16:43:19 +0900 Subject: [PATCH 1/2] Allow override method/property for ParamsSource --- src/BenchmarkDotNet/Running/BenchmarkConverter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BenchmarkDotNet/Running/BenchmarkConverter.cs b/src/BenchmarkDotNet/Running/BenchmarkConverter.cs index 6ff57f8f87..5c9250a579 100644 --- a/src/BenchmarkDotNet/Running/BenchmarkConverter.cs +++ b/src/BenchmarkDotNet/Running/BenchmarkConverter.cs @@ -308,7 +308,7 @@ private static object Map(object providedValue, Type type) private static (MemberInfo source, object[] values) GetValidValuesForParamsSource(Type sourceType, string sourceName) { - var paramsSourceMethod = sourceType.GetAllMethods().SingleOrDefault(method => method.Name == sourceName && method.IsPublic); + var paramsSourceMethod = sourceType.GetAllMethods().FirstOrDefault(method => method.Name == sourceName && method.IsPublic); if (paramsSourceMethod != default) return (paramsSourceMethod, ToArray( @@ -316,7 +316,7 @@ private static (MemberInfo source, object[] values) GetValidValuesForParamsSourc paramsSourceMethod, sourceType)); - var paramsSourceProperty = sourceType.GetAllProperties().SingleOrDefault(property => property.Name == sourceName && property.GetMethod.IsPublic); + var paramsSourceProperty = sourceType.GetAllProperties().FirstOrDefault(property => property.Name == sourceName && property.GetMethod.IsPublic); if (paramsSourceProperty != default) return (paramsSourceProperty, ToArray( From 247914d1bba8ff0a2f75a880db4ced70c68ce9cf Mon Sep 17 00:00:00 2001 From: neuecc Date: Fri, 19 Sep 2025 17:20:52 +0900 Subject: [PATCH 2/2] add tests for allow ParamsSource override --- .../ParamSourceTests.cs | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/tests/BenchmarkDotNet.IntegrationTests/ParamSourceTests.cs b/tests/BenchmarkDotNet.IntegrationTests/ParamSourceTests.cs index e58f6a67d7..82255131fd 100644 --- a/tests/BenchmarkDotNet.IntegrationTests/ParamSourceTests.cs +++ b/tests/BenchmarkDotNet.IntegrationTests/ParamSourceTests.cs @@ -14,7 +14,7 @@ namespace BenchmarkDotNet.IntegrationTests { - public class ParamSourceTests: BenchmarkTestExecutor + public class ParamSourceTests : BenchmarkTestExecutor { public ParamSourceTests(ITestOutputHelper output) : base(output) { } @@ -204,5 +204,43 @@ public void SourceWithExplicitCastToTarget_InProcessToolchain_Throws() // public void SourceWithExplicitCastToTarget_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(SourceWithExplicitCastToTarget), toolchain); Assert.ThrowsAny(() => CanExecuteWithExtraInfo(typeof(SourceWithExplicitCastToTarget), InProcessEmitToolchain.Instance)); } + + public abstract class OverridePropertyBase + { + public abstract int[] GetSourceProperty { get; } + + [ParamsSource(nameof(GetSourceProperty))] + public int ParamsTarget { get; set; } + } + + public class OverrideProperty : OverridePropertyBase + { + public override int[] GetSourceProperty => new int[] { 1, 2, 3 }; + + [Benchmark] + public int Benchmark() => ParamsTarget; + } + + [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)] + public void OverrideProperty_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(OverrideProperty), toolchain); + + public abstract class OverrideMethodBase + { + public abstract int[] GetSourceMethod(); + + [ParamsSource(nameof(GetSourceMethod))] + public int ParamsTarget { get; set; } + } + + public class OverrideMethod : OverrideMethodBase + { + public override int[] GetSourceMethod() => new int[] { 1, 2, 3 }; + + [Benchmark] + public int Benchmark() => ParamsTarget; + } + + [Theory, MemberData(nameof(GetToolchains), DisableDiscoveryEnumeration = true)] + public void OverrideMethod_Succeeds(IToolchain toolchain) => CanExecuteWithExtraInfo(typeof(OverrideMethod), toolchain); } }