Search code examples
c#debuggingbuildvisual-studio-2022record

'record' keyword not working in Visual Studio


When I try to use the record keyword in my C# WPF .NET Framework file, it is recognised as a keyword, in the sense in appears in the code completion drop-down menu when you start typing, but then does not turn blue or work as it should.

keyword appearing in drop-down menu

When I use the record keyword, the error message is CS0246: The type or namespace name could not be found (are you missing a using directive or an assembly reference?).

error message when I use the keyword

According to what I've looked up, the record keyword should not need any special directives to use. I have also tried changing the .NET version, adding all the extra modifications in the visual installer, and repairing the installation many times.

I tested whether the keyword functioned correctly in some console apps. It worked in the regular .NET console app, but did not work in the .NET Framework console app.

Does anybody know a fix for this issue, or have any other ideas as to how I could tackle it? Thank you very much


Solution

  • The record keyword was added in C# 9.

    .NET Framework projects default to an older C# 7.3

    The .NET (NOT framework) Console apps you see default to a higher version (10 for .NET 6, 11 for .NET 7, 12 for .NET 8), so that's why there are no issues there.

    For .NET Framework, you could use records in a limited and possibly confusing and misleading way if you manually edited your csproj file and added <LangVersion>9.0</LangVersion> under <PropertyGroup>:

    record Foo() // cannot inline declaration such as Foo(int Bar) due to no init support
    {
        // no init modifier possible for the property
        public int NotInitOnlyProperty{ get; set; }
    }
    

    We don't get the init-only properties that are default for records, but we do get value equality and the with keyword.

    var foo = new Foo();
    
    // with works
    var bar = foo with { NotInitOnlyProperty = 4 };
    
    var baz = new Foo
    {
        NotInitOnlyProperty = 4
    };
    Console.WriteLine(bar == baz); // true - value semantics
    

    I haven't tested this more than the snippet above, so obvious disclaimers apply.