Skip to content

Precision gap: self-owned-template-part exemption doesn't cover a local-variable/pattern-match capture #222

Description

@PhysShell

Found by: the issue #201 oracle sweep, docs/notes/oracle-sweep-2026-07-10.md; catalogued as docs/notes/field-notes-patterns.md entry 16.

The pattern

A named template part (GetTemplateChild/Template.FindName) is owned by the control's own template — its lifetime is bound to the control instance, the exact shape the shipped self-owned-template-part exemption already covers (docs/notes/real-world-mining.md's GetTemplateChild/FindName fix). That fix keys off a field assignment (_field = GetTemplateChild(...) as T); both examples below store the template part in a local instead.

// MahApps.Metro, MetroWindow.cs:1447-1449
if (this.GetTemplateChild(PART_Content) is MetroContentControl metroContentControl)
{
    metroContentControl.TransitionCompleted += (_, _) => this.RaiseEvent(...);   // <- flagged
}
// AvalonEdit, OverloadViewer.cs:58-64
public override void OnApplyTemplate() {
    base.OnApplyTemplate();
    Button upButton = (Button)this.Template.FindName("PART_UP", this);
    upButton.Click += (sender, e) => { ... };   // <- flagged
    Button downButton = (Button)this.Template.FindName("PART_DOWN", this);
    downButton.Click += (sender, e) => { ... };  // <- flagged
}

Evidence — confirmed in 2 separate repos

  • MahApps.Metro src/MahApps.Metro/Controls/MetroWindow.cs:1447-1449 (an is T x pattern-match local)
  • AvalonEdit ICSharpCode.AvalonEdit/CodeCompletion/OverloadViewer.cs:58,64 (a plain local variable, via FindName rather than GetTemplateChild)

Suggested direction (not prescriptive)

Extend the self-owned-template-part exemption's recognition from "assigned to a field" to "the result of GetTemplateChild/Template.FindName, however it's captured" — a plain local, an is T x pattern variable, or a field, all equally template-owned.

Scope

No analyzer code changed as part of the sweep — this issue tracks the fix as its own unit of work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions