Can we use Records in C# 8.0?
Asked Answered
I

3

16

I have a project using .NET Standard 2.1 and .NET core 3.1 - so the C# version is 8.0

According to a few articles I found (e.g. one, two), it should be possible to define a record type using this syntax:

public class MyRecord(string Input1, int Input2);

But I get many compilation errors, as this syntax for defining a class is clearly incorrect.

Are these articles misleading?

Is the only way to use records to upgrade to C# 9.0, and therefore .NET 5.0?

Inhaul answered 25/5, 2021 at 11:32 Comment(6)
public record and not public classGracegraceful
changing it to record gives Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported - it seems to be a feature of c# 9Inhaul
learn.microsoft.com/en-us/dotnet/csharp/language-reference/… - first sentence Beginning with C# 9...Gracegraceful
@RandRandom Yes, the question is whether the articles which claim that its possible in c# 8 are incorrectInhaul
Yes, they're incorrect - but reasonably so, given that the first states: "Again, before I go any further, I would like to point out that as I'm writing this, the feature-set for C# 8.0 still hasn't been decided. This means that information written here is subject to change." and the second states: "Just to be clear, this was initially planned for C# version 8 but due to other more important features and the complexity of this feature it has been postponed for a point version with unclear path if it will be in 8.1 or 8.2 etc"Viguerie
But also, see btburnett.com/csharp/2020/12/11/…Viguerie
P
21

I have a project using .NET Standard 2.1 and .NET core 3.1 - so the C# version is 8.0

Incorrect. The default C# version is 8.0, but you can use any language version you like (as long as you have the correct build tools and build SDK), simply by changing the language version. The easiest way to do this is in the csproj:

<PropertyGroup>
    <LangVersion>9.0</LangVersion>
</PropertyGroup>

There are some caveats:

  1. some features require additional type definitions which will be missing on earlier frameworks, but can be added manually or via additional nuget package references; in the case of records, this may require IsExternalInit, which PMF shows you how to define, here
  2. some features require runtime features, and can not work on earlier frameworks, such as the new default interface implementation feature
  3. you won't get any support from Microsoft - if it works, great; if it doesn't; meh

Is the only way to use records to upgrade to C# 9.0, and therefore .NET 5.0?

No; you need the .NET 5 build SDK, but you can still target .NET Core 3.1 etc.

Pinnule answered 25/5, 2021 at 11:45 Comment(0)
E
14

To avoid the error Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported, just add the following code anywhere in your project:

using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
    /// <summary>
    /// Reserved to be used by the compiler for tracking metadata.
    /// This class should not be used by developers in source code.
    /// This dummy class is required to compile records when targeting .NET Standard
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public static class IsExternalInit
    {
    }
}

Then the record types should be netstandard2.0-compliant, meaning they work also under i.e. .NET 4.8.

Edette answered 25/5, 2021 at 11:40 Comment(0)
I
5

Thanks to the other 2 answers I now understand the problem I am having

My csproj contains this line

<LangVersion>latest</LangVersion>

So I am using C# 9.0, and in fact I am able to use the record keyword like this

public record MyRecord
{
    public string Input1 { get; set; }
    public int Input2 { get; set; }
}

But if I want to use the more concise syntax from my question, I would need to include IsExternalInit from PMF's answer

In fact that would let me define it as

public sealed record MyRecord(string Input1, int Input2);

Also worth noting Jon Skeet's comment that this may eventually be released to some version of 8.X

Inhaul answered 25/5, 2021 at 11:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.