error CS0542: 'Queue': member names cannot be the same as their enclosing type — a Razor component is
a C# class named after its file, and you just gave it a member with that same name.
Queue.razor compiles to class Queue. The directive @inject QueueService Queue
adds a property called Queue to that class, which C# forbids — a member cannot share its type's name.
Rename the injected member (QueueSvc, Queues, anything else) and the page keeps its
file name, its route and its class.
The error
The compiler reports it against the @inject line of the .razor file:
error CS0542: 'Queue': member names cannot be the same as their enclosing type
Why it happens
Razor turns every .razor file into a partial class whose name is the file name, so the staff queue
page at Components/Pages/Staff/Queue.razor is Queue. @inject T Name becomes
a property: [Inject] T Name { get; set; }. Put the two together and the generated class is
class Queue { QueueService Queue { get; set; } }, which trips a rule older than Blazor:
a member cannot be named after the type that contains it.
The trap is that the same line is legal one file over. Kiosk.razor and Board.razor both
say @inject QueueService Queue without complaint, because their classes are called Kiosk and Board.
The AI named the service after the concept the page is about — natural, and wrong exactly when the page is about
the same concept.
The fix
@page "/staff/queue"
@rendermode InteractiveServer
@attribute [Microsoft.AspNetCore.Authorization.Authorize(Roles = ClinicLive.Data.DbSeeder.ReceptionRole)]
@implements IAsyncDisposable
@using ClinicLive.Services
@inject QueueService QueueSvc
@inject ClinicTime Clinic
@inject NavigationManager Navigation
Every use in the file changes from Queue.CheckInAsync(...) to QueueSvc.CheckInAsync(...).
The alternative — renaming the component — is worse: the file name is the URL-facing identity of the page, and
the injected property is nobody's business but the file's. Pick a naming habit and keep it:
Svc, Service, or the plural.
Where it bit us
Season one, Part 7 (tag part-07 in
the repo), when the live queue arrived and the AI
injected QueueService Queue into Queue.razor. Then again in
Part 8 (tag part-08): a member named
Chat injected into Chat.razor. Identical mistake, one part apart. The lesson is not
about CS0542 — it is that an assistant does not learn between your sessions, so it repeats its habits, and a log
of its recurring mistakes is worth as much as the log of your prompts.
What the AI got wrong: the same thing twice. It is a good habit to keep a short list of an assistant's repeat offenders and paste it into the prompt when you start a similar task — "inject services with a Svc suffix" would have prevented the second one.
Frequently asked
- Why does an inject directive cause CS0542 in a Blazor component?
- A .razor file compiles to a class with the file's name, and the inject directive generates a property with the name you gave it. If the property name equals the file name, for example injecting a member called Queue into Queue.razor, C# rejects it because a member cannot share its enclosing type's name.
- Can I keep the injected property named Queue?
- Only by renaming the component so its class is no longer called Queue, which changes the file and usually the route. Renaming the injected member, for example to QueueSvc, is the simpler fix and is what ClinicLive did.
- Why does the same inject line work in Kiosk.razor?
- Because that component's class is named Kiosk, so a member called Queue does not clash. The rule only bites when the member name and the component's file name are identical.
More decoded errors in the Fixes category; the app this came from starts at From Prompt to Production, Part 1.