Skip to content

Invalid codegen for Enumerable.Empty returned from ParamsSource #1812

@BoundedChenn31

Description

@BoundedChenn31

Description:
Attempt to parameterize property of type IEnumerable<T> with Enumerable.Empty<T>() or Enumerable.Repeat<T>(element, count) using ParamsSource attribute causes compilation error in codegen compilation error CS0266: Cannot implicitly convert type 'object' to 'System.Collections.Generic.IEnumerable'. An explicit conversion exists (are you missing a cast?) because of lines like

instance.A = (System.Object)BenchmarkDotNet.Parameters.ParameterExtractor.GetParameter(instance.ValuesForA, 1);;

Benchmark code:

public class ParamsSourceIntro
{
    public IEnumerable<IEnumerable<int>> ValuesForA()
    {
        yield return Enumerable.Empty<int>();
        yield return Enumerable.Repeat(1, 1);
    }

    [ParamsSource(nameof(ValuesForA))]
    public IEnumerable<int> A { get; set; }

    [Benchmark]
    public int[] Benchmark() => A.ToArray();
}

class Program
{
    static void Main(string[] args)
    {
        var _ = BenchmarkRunner.Run<ParamsSourceBug>();
    }
}

Logs:
Log with compilation error: BenchmarkDotNetParamsSourceBug.ParamsSourceBug-20210923-021529.log
Autogenerated project: 397b1fac-e83d-4694-8454-8c0fcba111a5.zip

Workarounds:

  1. Use ArgumentsSource attribute;
  2. Change type of parameterized property to object and cast it back later;
  3. Wrap IEnumerable in it's own type record Wrapper<T>(IEnumerable<T> Collection).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions