Round #711

10 May 2026, 15:10· csharp· Meta-Llama-3.3-70B-Instruct· r13-clean-hints
Complexity
band 0
ZP / UO / OBS
4 / 0 / 0
Journey weight
340
Lightshift ΔL
+0.00

Prompt

Write a Roslyn ISourceGenerator that emits boilerplate INotifyPropertyChanged for all [Notify] attributed properties.

Zero-point index (what the engine surfaced)

ZPI-ZPI-0010 | 2026-05-10T15:10:57Z Write a Roslyn ISourceGenerator that emits boilerplate INotifyPropertyChanged for all [Notify] attributed properties. ZERO POINT — 4 entries (structural invariants) ● hsl(85.45, 100%, 15%) IIncrementalGenerator [contract] ● hsl(215.26, 100%, 15%) ISourceGenerator [contract] ● hsl(81.32, 100%, 15%) DiagnosticAnalyzer [contract] ● hsl(258.54, 100%, 15%) CodeFixProvider [contract] UNOBSERVED — 0 entries (implied truths) OBSERVED — 0 entries (explicit in request) COMPLEXITY │ 4 entries │ spread: 0° │ band: LOW

Baseline response (no ZPI)

Here's an example implementation of a Roslyn `ISourceGenerator` that emits boilerplate `INotifyPropertyChanged` code for properties attributed with `[Notify]`: ```csharp using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System; using System.Collections.Generic; using System.Linq; using System.Text; [Generator] public class NotifyPropertyChangedGenerator : ISourceGenerator { public void Execute(GeneratorExecutionContext context) { var syntaxTrees = context.Compilation.SyntaxTrees; var notifyProperties = new Dictionary<string, List<PropertyDeclarationSyntax>>(); // Find all properties with the [Notify] attribute foreach (var tree in syntaxTrees) { var root = tree.GetRoot(); var properties = root.DescendantNodes().OfType<PropertyDeclarationSyntax>(); foreach (var property in properties) { var attribute = property.AttributeLists .SelectMany(al => al.Attributes) .FirstOrDefault(a => a.Name.ToString() == "Notify"); if (attribute != null) { var className = property.Ancestors().OfType<ClassDeclarationSyntax>().FirstOrDefault()?.Identifier.Text; if (!notifyProperties.TryGetValue(className, out var classProperties)) { classProperties = new List<PropertyDeclarationSyntax>(); notifyProperties.Add(className, classProperties); } classProperties.Add(property); } } } // Generate code for each class with notify properties foreach (var (className, properties) in notifyProperties) { var classCode = GenerateClassCode(className, properties); context.AddSource($"{className}.g.cs", SourceText.From(classCode, Encoding.UTF8)); } } private string GenerateClassCode(string className, List<PropertyDeclarationSyntax> properties) { var sb = new StringBuilder(); // Using statements sb.AppendLine("using System.ComponentModel;"); sb.AppendLine("using System.Runtime.CompilerServices;"); sb.AppendLine(); // Class declaration sb.AppendLine($"public partial class {className} : INotifyPropertyChanged"); sb.AppendLine("{"); // PropertyChanged event sb.AppendLine(" public event PropertyChangedEventHandler PropertyChanged;"); sb.AppendLine(); // OnPropertyChanged method sb.AppendLine(" protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)"); sb.AppendLine(" {"); sb.AppendLine(" PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));"); sb.AppendLine(" }"); sb.AppendLine(); // Property setters foreach (var property in properties) { var propertyName = property.Identifier.Text; var propertyType = property.Type.ToString(); sb.AppendLine($" private {propertyType} _{propertyName};"); sb.AppendLine($" public {propertyType} {propertyName}"); sb.AppendLine(" {"); sb.AppendLine($" get => _{propertyName};"); sb.AppendLine($" set"); sb.AppendLine(" {"); sb.AppendLine($" if (value == _{propertyName}) return;"); sb.AppendLine($" _{propertyName} = value;"); sb.AppendLine($" OnPropertyChanged(nameof({propertyName}));"); sb.AppendLine(" }"); sb.AppendLine(" }"); sb.AppendLine(); } sb.AppendLine("}"); return sb.ToString(); } public void Initialize(GeneratorInitializationContext context) { // No initialization needed } } // Attribute for marking properties to generate notify code [AttributeUsage(AttributeTargets.Property)] public class NotifyAttribute : Attribute { } ``` To use this generator, simply add the `[Notify]` attribute to the properties you want to generate `INotifyPropertyChanged` code for: ```csharp public class MyClass { [Notify] public string MyProperty { get; set; } [Notify] public int MyOtherProperty { get; set; } } ``` The generator will automatically create a partial class with the same name as `MyClass` and implement the `INotifyPropertyChanged` interface, including the `PropertyChanged` event and `OnPropertyChanged` method. The property setters will also be updated to call `OnPropertyChanged` when the property value changes. Note that this implementation assumes that the properties are auto-implemented and have a private backing field. If your properties have a different implementation, you may need to modify the generator accordingly.

Enhanced response (with ZPI)

Here's a fully implemented Roslyn `ISourceGenerator` that emits boilerplate `INotifyPropertyChanged` for all `[Notify]` attributed properties: ```csharp using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System; using System.Collections.Generic; using System.Linq; using System.Text; [Generator] public class NotifyPropertyChangedGenerator : ISourceGenerator { public void Execute(GeneratorExecutionContext context) { var syntaxTrees = context.Compilation.SyntaxTrees; var notifyProperties = new List<NotifyProperty>(); // Find all properties with the [Notify] attribute foreach (var tree in syntaxTrees) { var root = tree.GetRoot(); var properties = root.DescendantNodes().OfType<PropertyDeclarationSyntax>(); foreach (var property in properties) { var attribute = property.AttributeLists .SelectMany(al => al.Attributes) .FirstOrDefault(a => a.Name.ToString() == "Notify"); if (attribute != null) { notifyProperties.Add(new NotifyProperty { PropertyName = property.Identifier.Text, PropertyType = property.Type.ToString(), ContainingType = property.Ancestors().OfType<ClassDeclarationSyntax>().FirstOrDefault()?.Identifier.Text, ContainingNamespace = property.Ancestors().OfType<NamespaceDeclarationSyntax>().FirstOrDefault()?.Name.ToString() }); } } } // Generate the boilerplate code var code = GenerateCode(notifyProperties); // Add the generated code to the compilation context.AddSource("NotifyPropertyChanged.g.cs", SourceText.From(code, Encoding.UTF8)); } private string GenerateCode(List<NotifyProperty> notifyProperties) { var code = new StringBuilder(); // Generate the using statements code.AppendLine("using System.ComponentModel;"); code.AppendLine(); // Generate the implementation for each property foreach (var property in notifyProperties) { code.AppendLine($"namespace {property.ContainingNamespace}"); code.AppendLine("{"); code.AppendLine($" public partial class {property.ContainingType} : INotifyPropertyChanged"); code.AppendLine(" {"); code.AppendLine($" private {property.PropertyType} _{property.PropertyName};"); code.AppendLine(); code.AppendLine($" public {property.PropertyType} {property.PropertyName}"); code.AppendLine(" {"); code.AppendLine($" get => _{property.PropertyName};"); code.AppendLine($" set"); code.AppendLine(" {"); code.AppendLine($" if (value == _{property.PropertyName}) return;"); code.AppendLine($" _{property.PropertyName} = value;"); code.AppendLine($" OnPropertyChanged(nameof({property.PropertyName}));"); code.AppendLine(" }"); code.AppendLine(" }"); code.AppendLine(); code.AppendLine(" public event PropertyChangedEventHandler PropertyChanged;"); code.AppendLine(); code.AppendLine(" protected virtual void OnPropertyChanged(string propertyName)"); code.AppendLine(" {"); code.AppendLine(" PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));"); code.AppendLine(" }"); code.AppendLine(" }"); code.AppendLine("}"); code.AppendLine(); } return code.ToString(); } public void Initialize(GeneratorInitializationContext context) { } private class NotifyProperty { public string PropertyName { get; set; } public string PropertyType { get; set; } public string ContainingType { get; set; } public string ContainingNamespace { get; set; } } } [AttributeUsage(AttributeTargets.Property)] public class NotifyAttribute : Attribute { } ``` This `ISourceGenerator` finds all properties with the `[Notify]` attribute and generates the boilerplate code for implementing `INotifyPropertyChanged`. The generated code includes the `OnPropertyChanged` method and the event handler for the `PropertyChanged` event. To use this generator, simply add the `[Notify]` attribute to the properties you want to generate the boilerplate code for: ```csharp public class MyClass { [Notify] public string MyProperty { get; set; } } ``` The generator will automatically generate the necessary code to implement `INotifyPropertyChanged` for the `MyProperty` property.

Grader chain

Each grader reads the same baseline + enhanced pair and casts an independent verdict. Disagreement is the framework's own signal — not noise to be averaged away.

V1samba/Meta-Llama-3.3-70B-Instruct
Better
V4qwen2.5-coder-3b-instruct
Better
V5openrouter/qwen/qwen3-235b-a22b-2507
Worse
V7qwen2.5-coder-7b-instruct
Better
V8openai/gpt-4.1
Same
V9anthropic/claude-opus-4-7
Worse
V12openai/gpt-4o
Better

Comments

Our grader said what it said. What do you say? Comment as a guest below.

No comments yet. Be the first to say what you make of this round.

← back to all rounds