Skip to content

[SmartEnum] generated sealed type conflicts with source generators that add virtual members #24

Closed

Description

@christophdebaene

I hit a source-generator interoperability issue when combining the library with Validly validation.

Minimal example:

using Thinktecture;
using Validly;

[SmartEnum<string>]
[Validatable]
public partial class OrderStatus         
{
   public static readonly OrderStatus Pending = new("Pending"); 
   public static readonly OrderStatus Processing = new("Processing");
   public static readonly OrderStatus Completed = new("Completed");
   public static readonly OrderStatus Cancelled = new("Cancelled");

   private ValidationMessage? AfterValidate(ValidationResult result)
   {
       return null;
   }
}

This produces compiler errors like:

'OrderStatus.Validate()' is a new virtual member in sealed type 'OrderStatus'
'OrderStatus.ValidateAsync(CancellationToken)' is a new virtual member in sealed type 'OrderStatus'

From what I can tell, the SmartEnum source generator makes the generated partial type sealed, while Validly generates virtual Validate/ValidateAsync members for [Validatable] classes.

Activity

  1. PawelGerr commented on Oct 1, 2026

    @PawelGerr
    Owner

    There are two separate problems here.

    1. virtual in a sealed type: A source generator cannot see the output of another source generator. Validly therefore sees a class without sealed and generates virtual members, while this library adds sealed in its own partial part. You can fix this by declaring the class as public sealed partial class OrderStatus. Validly then generates the members without virtual.

    2. Analyzer error TTRESG001 for _validationContext: After the first fix, the analyzer reports the field _validationContext that Validly generates. This error is intended. The items of a Smart Enum are static instances that all threads share, so a Smart Enum must not have mutable instance state. Validly writes the validation context into that field on every validation. Two concurrent validations of OrderStatus.Pending would overwrite the context of each other.

    For this reason, [Validatable] is not supported on a Smart Enum. It is also not needed: an item is valid by construction, and an invalid key is rejected by Get and TryGet.

  2. christophdebaene commented on Oct 6, 2026

    @christophdebaene
    Author

    Thank you very much for your quick answer!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions