I'm Manu. You can find more information about me on...
Legal: Impressum (Site Notice)
A source code only package which allows you to use C# 9's init and record features in older target frameworks like .NET Standard 2.0 or the "old" .NET Framework by providing a polyfill for the IsExternalInit class.
Home Page: https://www.nuget.org/packages/IsExternalInit
License: MIT License
I'm Manu. You can find more information about me on...
Legal: Impressum (Site Notice)
I'm trying to use this in a .Net Framework 3.5 project with the language version set to C#9, like so:
public record TestRecord
{
public string Name { get; init; }
}
I am getting the following error:
[CS0656] Missing compiler required member 'System.Type.op_Equality'
Is it even possible to use C# 9 records in .Net Framework 3.5?
Hey there,
I love your Nullable and IsExternalInit polyfills. I noticed there's another (slightly more involved) one that would be awesome to combine with those two: support for range syntax on NS2 (probably others too?).
The code needed to support that is basically https://github.com/devlooped/avatar/blob/main/src/Avatar.UnitTests/Range.cs (which I copy-pasted from corefx, since that was an earlier, simpler version), which you can see working on that net472 multi-targeting project. I use that same file in other NS2 projects too.
I'm just too lazy to clone the entire approach you already have, so I thought I might just suggest you do it instead, he :).
And FWIW, I think a meta-package that brought them all would be nice too :).
Unlike other polyfill packages where you can get away with declaring attributes only where the TFM does not declare them, IsExternalInit
must be declared in the same assembly forever and for all TFMs or else it's a binary breaking change.
I see in your nuspec that you omit the declaration for net5 but you can't do that. You must declare it there as well.
The reason being the compiler generates metadata on the init
property accessors that references this attribute using its assembly-qualified type name. When other assemblies reference this one and invoke an init
accessor, the compiler embeds that exact same assembly-qualified reference into their invocation of that accessor. Now imagine this referencing library runs in a process where the referenced library is no longer the one that targeted net472 but targets net5. The CLR will throw a MissingMethodException when it encounters the init accessor because the attribute on the accessor does not match the IsExternalInit reference in the caller.
I don't understand.
I have a netstandard2.0 assembly using LangVersion 9.0 and with this added:
namespace System.Runtime.CompilerServices
{
internal class IsExternalInit { }
}
Then init works.
I can reference this assembly from net5.0 assemblies (using default LangVersion 9.0) and from .NET framework 4.7.2 using default LangVersion (assume 7.3). So why would I need this?
I'm trying to upgrade my solution to VS 2022, but if I build it I'm getting duplicate definition errors that weren't there before with VS 2019. I guess this is caused by the new .net 6 sdk?
I think a simple future proof fix would be to wrap the source code in another #if block
#if !NET
...
#endif
since NET
is defined for .net 5 and later.
In the same vein as Nullable and this project, this attribute is missing in older TFMs and is required to create a module initializer:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ModuleInitializerAttribute : Attribute { }
}
C# 9 proposal: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/module-initializers
It's already shipped too :)
When using the package I get this error with my records. (net461/netstandard2.0/netstandard2.1)
But additonally using
namespace System.Runtime.CompilerServices
{
internal class IsExternalInit { }
}
will show that this is already included by the package.
When I build the solution by starting a project within the solution that references the project using IsExternalInit, it compiles. But when I compile the standalone project it shows this error for each record.
It used to work not too long ago, but now it doesn't, very strange. I'm using VS 17.2 and 17.3 Preview.
Only using my own IsExternalInit works every time, but I would like to use the package...
It might be Microsoft's fault but on Visual Studio 17.2.0 & 17.2.1 a build of a solution targeting multiple frameworks and containing your package works fine, whereas a rebuild always fails with "Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported".
It can easily be reproduced with your test project PackageReference.MultiTarget.
Clean & Build works fine.
Rebuild fails.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.