Search code examples
c#type-conversionimplicit-conversion

C# record struct implicit conversion operator not working


I have a readonly record struct with five properties and two implicit operators.

readonly record struct Puzzle ()
{
    public required string Input { get; init; }

    public required string Sample { get; init; }

    public string? P2Sample { get; init; } = null;

    public required Func<string, int> Part1 { get; init; }

    public required Func<string, int> Part2 { get; init; }

    public static implicit operator Puzzle ((string input, string p1Sample, string? p2Sample, Func<string, int> part1, Func<string, int> part2) value) => new()
    {
        Input = value.input,
        Sample = value.p1Sample,
        P2Sample = value.p2Sample,
        Part1 = value.part1,
        Part2 = value.part2
    };

    public static implicit operator Puzzle ((string input, string sample, Func<string, int> part1, Func<string, int> part2) value) => 
        (value.input, value.sample, null, value.part1, value.part2);
}

However, the second conversion operator (four element tuple) doesn't work at all - as if the compiler doesn't know it exists.

When I try to use it like this:

new Puzzle[] {
    (Inputs.Day1Input, Inputs.Day1_1Sample, Inputs.Day1_2Sample, Day1_1.ExtractSum, Day1_2.ExtractSum),
    (Inputs.Day2Input, Inputs.Day2Sample, Day2.MinColorPowers, Day2.MinColorPowers)
}

The first element works perfectly fine, but the second one throws an error - CS8135: Tuple with 4 elements cannot be converted to type 'Puzzle'.

I have clearly defined an operator to convert a four-element tuple to Puzzle - so why does this happen?


Solution

  • When I try this code, it compiles just fine:

        Func<string, int> ExtractSum = int.Parse;
        var puzzle = new Puzzle[] {
            ("", "", "", ExtractSum, ExtractSum),
            ("", "", MinColorPowers, MinColorPowers)
        };
        int MinColorPowers(string s) => int.Parse(s);
    

    But if I change the signature of the MinColorPowers function, I get the same error you're getting:

        float MinColorPowers(string s) => int.Parse(s);
    

    Chances are, the method you're passing in doesn't match the delegate signature for your tuple type. Try explicitly casting the delegate arguments you're passing in to the types you're expecting. It will probably give you a more informative error.