Skip to content

x:Bind does not work with C# record #5315

@Marv51

Description

@Marv51

Describe the bug
I am try to x:bind a c# 9 record to the ItemsSource of an ItemsRepeater, with a corresponding DataTemplate. However, compilation fails with

XamlTypeInfo.g.cs(6465,13,6465,23): error CS8852: Init-only property or indexer 'BlogPost.Title' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor.

Steps to reproduce the bug

<ItemsRepeater ItemsSource="{x:Bind BlogPosts}">
    <ItemsRepeater.ItemTemplate>
        <DataTemplate x:DataType="local:BlogPost">
                <TextBlock>{x:Bind Title}</TextBlock>
        </DataTemplate>
    </ItemsRepeater.ItemTemplate>
</ItemsRepeater>
public record BlogPost(string Title, string Teaser, Uri? Url, DateTime Published);

public partial class MyPage: Page, INotifyPropertyChanged
{
    public ObservableCollection<BlogPost> BlogPosts { get; } = new()
    {
        new BlogPost("Test1", "Testing", null, DateTime.Now),
        new BlogPost("Test2", "Testing2", null, DateTime.Now),
        new BlogPost("Test2", "Testing2", null, DateTime.Now),
    };
// shortened
}

Version Info

NuGet package version:
WinUI 3 - Windows App SDK 0.8: 0.8.0

Windows app type:

UWP Win32
Yes
Windows 10 version Saw the problem?
Insider Build (xxxxx)
21H1 (19043) Yes
October 2020 Update (19042)
May 2020 Update (19041)
November 2019 Update (18363)
May 2019 Update (18362)
October 2018 Update (17763)
April 2018 Update (17134)
Fall Creators Update (16299)
Creators Update (15063)
Device form factor Saw the problem?
Desktop Yes
Xbox
Surface Hub
IoT

Additional context
The error message is referring to this generated method in XamlTypeInfo.g.cs which tries to set a property on a record:

private void set_295_BlogPost_Title(object instance, object Value)
{
    var that = (global::BrandMatrix.BlogPost)instance;
    that.Title = (global::System.String)Value;
}

Init Only Setters also seem to be broken in the same way:

 public class BlogPost {
        public string Title { get; init; }
        //...
    }

Of course private set; can be used as an alternative for now, but support for these features is needed to keep up with .net development. (Or at least a way better error message is needed)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Ready

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions