No trial. No credit card required. Just your GitHub account.
The future of .NET Standard

Since.NET 5 was announced, many of you have asked what this meansfor .NET Standard and whether it will still be relevant. In this post, I’m goingto explain how .NET 5 improves code sharing and replaces .NET Standard. I’llalso cover the cases where you still need .NET Standard.
For the impatient: TL;DR
.NET 5 will be a single product with a uniform set of capabilities and APIs thatcan be used for Windows desktop apps, cross-platform mobile apps, console apps,cloud services, and websites:
To better reflect this, we’ve updated thetarget framework names (TFMs):
net5.0
. This is for code that runs everywhere. It combines and replaces thenetcoreapp
andnetstandard
names. This TFM will generally only includetechnologies that work cross-platform (except for pragmatic concessions, like wealready did in .NET Standard).net5.0-windows
(and laternet6.0-android
andnet6.0-ios
). These TFMsrepresent OS-specific flavors of .NET 5 that includenet5.0
plus OS-specificfunctionality.
We won’t be releasing a new version of .NET Standard, but .NET 5 and all futureversions will continue to support .NET Standard 2.1 and earlier. You shouldthink ofnet5.0
(and future versions) as the foundation for sharing codemoving forward.
And since net5.0 is the shared base for all these new TFMs, that means that theruntime, library, and new language features are coordinated around this versionnumber. For example, in order to use C# 9, you need to usenet5.0
ornet5.0-windows
.
What you should target
.NET 5 and all future versions will always support .NET Standard 2.1 andearlier. The only reason to retarget from .NET Standard to .NET 5 is to gainaccess to more runtime features, language features, or APIs. So, you can think of.NET 5 as .NET Standard vNext.
What about new code? Should you still start with .NET Standard 2.0 or should yougo straight to .NET 5? It depends.
- App components. If you’re using libraries to break down your applicationinto several components, my recommendation is to use
netX.Y
whereX.Y
isthe lowest number of .NET that your application (or applications) aretargeting. For simplicity, you probably want all projects that make up yourapplication to be on the same version of .NET because it means you can assumethe same BCL features everywhere. - Reusable libraries. If you’re building reusable libraries that you plan onshipping on NuGet, you’ll want to consider the trade-off between reach andavailable feature set. .NET Standard 2.0 is the highest version of .NETStandard that is supported by .NET Framework, so it will give you the mostreach, while also giving you a fairly large feature set to work with. We’dgenerally recommend against targeting .NET Standard 1.x as it’s not worth thehassle anymore. If you don’t need to support .NET Framework, then you caneither go with .NET Standard 2.1 or .NET 5. Most code can probably skip .NETStandard 2.1 and go straight to .NET 5.
So, what should you do? My expectation is that widely used libraries will end upmulti-targeting for both .NET Standard 2.0 and .NET 5: supporting .NET Standard2.0 gives you the most reach while supporting .NET 5 ensures you can leveragethe latest platform features for customers that are already on .NET 5.
In a couple of years, the choice for reusable libraries will only involve theversion number ofnetX.Y
, which is basically how building libraries for .NEThas always worked — you generally want to support some older version in orderto ensure you get the most reach.
To summarize:
- Use
netstandard2.0
to share code between .NET Framework and all otherplatforms. - Use
netstandard2.1
to share code between Mono, Xamarin, and .NET Core 3.x. - Use
net5.0
for code sharing moving forward.
Problems with .NET Standard
.NET Standard has made it much easier to create libraries that work on all .NETplatforms. But there are still three problems with .NET Standard:
- Itversions slowly, which means you can’t easily use thelatest features.
- It needs adecoder ring to map versions to .NETimplementations.
- Itexposes platform-specific features, which means you can’tstatically validate whether your code is truly portable.
Let’s see how .NET 5 will address all three issues.
Problem 1: .NET Standard versions slowly
.NET Standard was designed at a time where the .NET platforms weren’tconverged at the implementation level. This made writing code that needs to workin different environments hard, because different workloads used different .NETimplementations.
The goal of .NET Standard was to unify the feature set of the base class library(BCL), so that you can write a single library that can run everywhere. And thishas served us well: .NET Standard is supported by over 77% of the top 1000packages. And if we look at all packages on NuGet.org that have been updated inthe last 6 months, the adoption is at 58%.
But standardizing the API set alone creates a tax. It requires coordinationwhenever we’re adding new APIs — which happens all the time. The .NETopen-source community (which includes the .NET team) keeps innovating in the BCLby providing new language features, usability improvements, new cross-cuttingfeatures such asSpan<T>
, or supporting new data formats or networkingprotocols.
And while we can provide new types as NuGet packages, we can’t provide new APIson existing types this way. So, in the general sense, innovation in the BCLrequires shipping a new version of .NET Standard.
Up until .NET Standard 2.0, this wasn’t really an issue because we onlystandardizedexisting APIs. But in .NET Standard 2.1, we standardized brand newAPIs and that’s where we saw quite a bit of friction.
Where does this friction come from?
.NET Standard is an API set that all .NET implementations have to support, sothere is aneditorial aspect to it in that all APIs must bereviewed by the.NET Standard review board. The board is comprisedof .NET platform implementers as well as representatives of the .NET community.The goal is to only standardize APIs that we can truly implement in all currentand future .NET platforms. These reviews are necessary because there aredifferent implementations of the .NET stack, with different constraints.
We predicted this type of friction, which is why we said early on that .NETStandardwill only standardize APIs that were already shipped in atleast one .NET implementation. This seems reasonable at first, but then yourealize that .NET Standard can’t ship very frequently. So, if a featuremisses a particular release, you might have to wait for a couple of years beforeit’s even available and potentially even longer until this version of .NETStandard is widely supported.
We felt for some features that opportunity loss was too high, so we didunnatural acts to standardize APIs that weren’t shipped yet (such asIAsyncEnumerable<T>
). Doing this for all features was simply too expensive,which is why quite a few of them still missed the .NET Standard 2.1 train (suchas the new hardware intrinsics).
But what if there was a single code base? And what if that code base would haveto support all the aspects that make .NET implementations differ today, suchas supporting both just-in-time (JIT) compilation and ahead-of-time(AOT) compilation?
Instead of doing these reviews as an afterthought, we’d make all these aspectspart of the feature design, right from the start. In such a world, thestandardized API set is, by construction, the common API set. When a feature isimplemented, it would already be available for everyone because the code base isshared.
Problem 2: .NET Standard needs a decoder ring
Separating the API set from its implementation doesn’t just slow down theavailability of APIs. It also means that we need tomap .NET Standard versionsto their implementations. As someone who had to explain this table tomany people over time, I’ve come to appreciate just how complicated thisseemingly simple idea is. We’ve tried our best to make it easier, but in theend, it’s just inherent complexity because the API set and the implementationsare shipped independently.
We have unified the .NET platforms by adding yet another synthetic platformbelow them all that represents the common API set. In a very real sense, thisXKCD-inspired comic is spot on:
We can’t solve this problem without truly merging some rectangles in our layerdiagram, which is what .NET 5 does: it provides a unified implementation whereall parties build on the same foundation and thus get the same API shape andversion number.
Problem 3: .NET Standard exposes platform-specific APIs
When we designed .NET Standard,we had to make pragmaticconcessions in order to avoid breaking the library ecosystem toomuch. That is, we had to include some Windows-only APIs (such as file systemACLs, the registry, WMI, and so on). Moving forward, we will avoid addingplatform-specific APIs tonet5.0
,net6.0
and future versions. However, it’s impossible for us to predictthe future. For example, with Blazor WebAssembly we have recently added a newenvironment where .NET runs and some of the otherwise cross-platform APIs (suchas threading or process control) can’t be supported in the browser’s sandbox.
Many of you have complained that these kind of APIs feel like “landmines” – thecode compiles without errors and thus appears to being portable to any platform,but when running on a platform that doesn’t have an implementation for the givenAPI, you get runtime errors.
Starting with .NET 5, we’reshipping analyzers and code fixerswith the SDK that are on by default. This includes theplatform compatibilityanalyzer that detects unintentional use of APIs thataren’t supported on the platforms you intend to run on. This feature replacestheMicrosoft.DotNet.Analyzers.Compatibility
NuGet package.
Let’s first look at Windows-specific APIs.
Dealing with Windows-specific APIs
When you create a project targetingnet5.0
, you can reference theMicrosoft.Win32.Registry
package. But when you start using it, you’ll get thefollowing warnings:
private static string GetLoggingDirectory(){ using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Fabrikam")) { if (key?.GetValue("LoggingDirectoryPath") is string configuredPath) return configuredPath; } string exePath = Process.GetCurrentProcess().MainModule.FileName; string folder = Path.GetDirectoryName(exePath); return Path.Combine(folder, "Logging");}
CA1416: 'RegistryKey.OpenSubKey(string)' is supported on 'windows'CA1416: 'Registry.CurrentUser' is supported on 'windows'CA1416: 'RegistryKey.GetValue(string?)' is supported on 'windows'
You have three options on how you can address these warnings:
- Guard the call. You can check whether you’re running on Windows beforecalling the API by using
OperatingSystem.IsWindows()
. - Mark the call as Windows-specific. In some cases, it might make sense tomark the calling member as platform-specific via
[SupportedOSPlatform("windows")]
. - Delete the code. Generally not what you want because it means you losefidelity when your code is used by Windows users, but for cases where across-platform alternative exists, you’re likely better off using that overplatform-specific APIs. For example, instead of using the registry, you coulduse an XML configuration file.
- Suppress the warning. You can of course cheat and simply suppress thewarning, either via
.editorconfig
or#pragma warning disable
. However,you should prefer options (1) and (2) when using platform-specific APIs.
Toguard the call, use the new static methods on theSystem.OperatingSystem class, for example:
private static string GetLoggingDirectory(){ if (OperatingSystem.IsWindows()) { using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Fabrikam")) { if (key?.GetValue("LoggingDirectoryPath") is string configuredPath) return configuredPath; } } string exePath = Process.GetCurrentProcess().MainModule.FileName; string folder = Path.GetDirectoryName(exePath); return Path.Combine(folder, "Logging");}
Tomark your code as Windows-specific, apply the newSupportedOSPlatform
attribute:
[SupportedOSPlatform("windows")]private static string GetLoggingDirectory(){ using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Fabrikam")) { if (key?.GetValue("LoggingDirectoryPath") is string configuredPath) return configuredPath; } string exePath = Process.GetCurrentProcess().MainModule.FileName; string folder = Path.GetDirectoryName(exePath); return Path.Combine(folder, "Logging");}
In both cases, the warnings for using the registry will disappear.
The key difference is that in the second example the analyzer will now issuewarnings for the call sites ofGetLoggingDirectory()
because it is nowconsidered to be a Windows-specific API. In other words, you forward therequirement of doing the platform check to your callers.
The[SupportedOSPlatform]
attribute can be applied to the member, type, orassembly level. This attribute is also used by the BCL itself. For example, theassemblyMicrosoft.Win32.Registry
has this attribute applied, which is howthe analyzer knows that the registry is a Windows-specific API in the firstplace.
Note that if you targetnet5.0-windows
, this attribute is automatically appliedto your assembly. That means using Windows-specific APIs fromnet5.0-windows
will never generate any warnings because your entire assembly is considered tobe Windows-specific.
Dealing with APIs that are unsupported in Blazor WebAssembly
Blazor WebAssembly projects run inside the browser sandbox, which constrainswhich APIs you can use. For example, while thread and process creation are bothcross-platform APIs, we can’t make these APIs work in Blazor WebAssembly, whichmeans they throwPlatformNotSupportedException
. We have marked these APIs with[UnsupportedOSPlatform("browser")]
.
Let’s say you copy & paste theGetLoggingDirectory()
method into a Blazor WebAssemblyapplication.
private static string GetLoggingDirectory(){ //... string exePath = Process.GetCurrentProcess().MainModule.FileName; string folder = Path.GetDirectoryName(exePath); return Path.Combine(folder, "Logging");}
You’ll get the following warnings:
CA1416 'Process.GetCurrentProcess()' is unsupported on 'browser'CA1416 'Process.MainModule' is unsupported on 'browser'
To deal with these warnings, you have basically the same optionsas with Windows-specific APIs.
You canguard the call:
private static string GetLoggingDirectory(){ //... if (!OperatingSystem.IsBrowser()) { string exePath = Process.GetCurrentProcess().MainModule.FileName; string folder = Path.GetDirectoryName(exePath); return Path.Combine(folder, "Logging"); } else { return string.Empty; }}
Or you can mark the member as being unsupported by Blazor WebAssembly:
[UnsupportedOSPlatform("browser")]private static string GetLoggingDirectory(){ //... string exePath = Process.GetCurrentProcess().MainModule.FileName; string folder = Path.GetDirectoryName(exePath); return Path.Combine(folder, "Logging");}
Since the browser sandbox is fairly restrictive, not all class libraries andNuGet packages should be expected to work in Blazor WebAssembly. Furthermore,the vast majority of libraries aren’t expected to support running in BlazorWebAssembly either.
That’s why regular class libraries targetingnet5.0
won’t see warnings forAPIs that are unsupported by Blazor WebAssembly. You have to explicitly indicatethat you intend to support your project in Blazor Web Assembly by adding the<SupportedPlatform>
item to your project file:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> </PropertyGroup> <ItemGroup> <SupportedPlatform Include="browser" /> </ItemGroup> </Project>
If you’re building a Blazor WebAssembly application, you don’t have to do thisbecause theMicrosoft.NET.Sdk.BlazorWebAssembly
SDK does this automatically.
.NET 5 as the combination of .NET Standard & .NET Core
.NET 5 and subsequent versions will be a single code base that supports desktopapps, mobile apps, cloud services, websites, and whatever environment .NET willrun on tomorrow.
You might think “hold on, this sounds great, but what if someone wants to createa completely new implementation”. That’s fine too. But virtually nobody willstart one from scratch. Most likely, it will be a fork of the current code base(dotnet/runtime). For example, Tizen (the Samsung platform for smartappliances) uses a .NET Core with minimal changes and a Samsung-specific appmodel on top.
Forking preserves a merge relationship, which allows maintainers to keep pullingin new changes from thedotnet/runtime repo, benefiting from BCL innovationsin areas unaffected by their changes. That’s very similar to how Linux distroswork.
Granted, there are cases where one might want to create a very different “kind”of .NET, such as a minimal runtime without the current BCL. But that wouldmean that it couldn’t leverage the existing .NET library ecosystem anyway, whichmeans it wouldn’t have implemented .NET Standard either. We’re generally notinterested in pursuing this direction, but the convergence of .NET Standard and.NET Core doesn’t prevent that nor does it make it any harder.
.NET versioning
As a library author, you’re probably wondering when .NET 5 will be widelysupported. Moving forward, we’ll ship .NET every year in November, with everyother year being a Long Term Support (LTS) release.
.NET 5 will ship in November 2020 and .NET 6 will ship in November 2021 as anLTS. We created this fixed schedule to make it easier for you to plan yourupdates (if you’re an app developer) and predict the demand for supported .NETversions (if you’re a library developer).
Thanks to the ability to install .NET Core side-by-side, new versions areadopted fairly fast with LTS versions being the most popular. In fact, .NET Core3.1 was the fastest adopted .NET version ever.
The expectation is that every time we ship, we ship all framework names inconjunction. For example, it might look something like this:
.NET 5 | .NET 6 | .NET 7 |
---|---|---|
net5.0 | net6.0 | net7.0 |
net6.0-android | net7.0-android | |
net6.0-ios | net7.0-ios | |
net5.0-windows | net6.0-windows | net7.0-windows |
net5.0-someoldos |
This means that you can generally expect that whatever innovation we did in theBCL, you’re going to be able to use it from all app models, no matter whichplatform they run on. It also means that libraries shipped for the latestnet
framework can always be consumed from all app models, as long as you run the latestversion of them.
This model removes the complexity around .NET Standard versioning because eachtime we ship, you can assume that all platforms are going to support the newversion immediately and completely. And we cement this promise by using theprefix naming convention.
New versions of .NET might add support for other platforms. For example, we will add support forAndroid and iOS, with .NET 6. Conversely, we might stop supporting platforms thatare no longer relevant. This is illustrated by the pretendnet5.0-someoldos
target framework that doesn’t exist in.NET 6. We have no plans for dropping a platform, but the model supports it. That would be a big deal, isn’t expected and would be announced long in advance. That’s the same model we had with .NET Standard, where, for example, there is nonew version of Windows Phone that implements a later version of .NET Standard.
Why there is no TFM for WebAssembly
We originally considered adding TFM for WebAssembly, such asnet5.0-wasm
. Wedecided against that for the following reasons:
- WebAssembly is more like an instruction set (such as x86 or x64) than like anoperating system. And we generally don’t offer divergent APIs between differentarchitectures.
- WebAssembly’s execution model in the browser sandbox is a key differentiator,but we decided that it makes more sense to only model this as a runtime check.Similar to how you check for Windows and Linux, you can use the
OperatingSystem
type. Since this isn’t about instruction set, the method is calledIsBrowser()
rather thanIsWebAssembly()
. - There areruntime identifiers (RID) for WebAssembly, called
browser
andbrowser-wasm
. They allow package authors to deploy different binarieswhen targeting WebAssembly in a browser. This is especially useful for native code which needs to be compiled to web assembly beforehand.
As described above, we have marked APIs that are unsupportedin the browser sandbox, such asSystem.Diagnostics.Process
. If you usethose APIs from inside a browser app, you’ll get a warning telling you that thisAPIs is unsupported.
Summary
net5.0
is for code that runs everywhere. It combines and replaces thenetcoreapp
andnetstandard
names. We also have platform-specific frameworks,such asnet5.0-windows
(and later alsonet6.0-android
, andnet6.0-ios
).
Since there is no difference between the standard and its implementation, you’llbe able to take advantage of new features much quicker than with .NET Standard.And due to the naming convention, you’ll be able to easily tell who can consumea given library — without having to consult the .NET Standard version table.
While .NET Standard 2.1 will be the last version of .NET Standard, .NET 5 andall future versions will continue to support .NET Standard 2.1 and earlier. Youshould think ofnet5.0
(and future versions) as the foundation for sharingcode moving forward.
Happy coding!
Author

Immo Landwerth is a program manager on the .NET Framework team at Microsoft. He specializes in API design, the base class libraries (BCL), and .NET Standard. He works on base class libraries which represents the core types of the .NET platform, such as string and int but also includes collections and IO.He's involved with portable class libraries and works on shipping more framework components in an out-of-band fashion via NuGet.
97 comments
Discussion is closed.Login to edit/delete existing comments.
Mil Yan Read moreYou say "net5.0 is for code that runs everywhere", but that does not appear to be true. You have moved what effectively is a package level check into runtime checks. When I look at the nuget I have no way of knowing if net50 built package is Linux or Mac compatible or if it has windows bindings which will pop up in runtime when it hits OperatingSystem.IsWindows() or fails to load assemblies.
I can understand this being easier for you, but whole reason behind a standard is not to be easy, its to be cross-platform compatible. And NetStandard assured of...Read lessYou say “net5.0 is for code that runs everywhere”, but that does not appear to be true. You have moved what effectively is a package level check into runtime checks. When I look at the nuget I have no way of knowing if net50 built package is Linux or Mac compatible or if it has windows bindings which will pop up in runtime when it hits OperatingSystem.IsWindows() or fails to load assemblies.
I can understand this being easier for you, but whole reason behind a standard is not to be easy, its to be cross-platform compatible. And NetStandard assured of that. You are not solving the problem, you are just dumping the problem in our lap.Eric Read moreThanks for this article.
I am quite curious to know the distribution of .NET developers by their product platform: mobile, Windows software, cloud oriented solutions, etc: quite different requirements!
net5.0, net5.0-windows, net6.0-android, net6.0-ios, etc: I understand they are always platform specific extensions, but their use should stay the exception, not the norm, isn't it? I mean, with .netCore and one unified .NET (5 and so on), we want to have the short version (e.g. .net5.0) as target for the large majority of products, don't we?
.NET Standard 2.0 made a lot of sense to me, to share dll between .NET Framework 4.x and...
Read lessThanks for this article.
I am quite curious to know the distribution of .NET developers by their product platform: mobile, Windows software, cloud oriented solutions, etc: quite different requirements!
net5.0, net5.0-windows, net6.0-android, net6.0-ios, etc: I understand they are always platform specific extensions, but their use should stay the exception, not the norm, isn’t it? I mean, with .netCore and one unified .NET (5 and so on), we want to have the short version (e.g. .net5.0) as target for the large majority of products, don’t we?
.NET Standard 2.0 made a lot of sense to me, to share dll between .NET Framework 4.x and .NET Core projects.
But I never really understood the purpose of .Net Standard 2.1 since only the .NET Core can consume it. So it is a fixed amount of libraries and every .NET Core and higher are super set of this .NET Std 2.1. So .NET Std 2.1 makes only sense for pure C# code without any external dependencies, right? For instance for generated code.In the product I am working on (containerized with .NET Core 3.1-Alpine as target, while developing under VS2019 in Windows), I’ve used .net Standard 2.1 only once, for a bunch of classes generated from a Thrift interface.
For another base common C# libraries, I started also with .NET Standard, but then realized the System.Text.Json are not in the standard (quite logic since it came after), so I simply targeted netcoreapp3.1. Goal of using System.Text.Json is to get rid of Newtonsoft.Json, I don’t want to see yet another dependency!Moreover, targeting the .NET Standard disable the advanced code analyzers (like FXCop) in Visual Studio. So not so great for delivering clean code!
Regarding C#9 only available for .NET 5, it is a bit a disappointment: with earlier versions, it was possible in VS to specify the C# and target framework more or less independently: one get work with the last version of C# and still target a lower .NET Core or Framework version.
So no way to use C#9 and still target netcoreapp3.1. with up-to-date Visual Studio ?Jon Miller So, now that you have net5.0-windows, I’m assuming you will be adding features such as Web Forms to it? I have a lot of Web Forms applications that will not be moved forward. Is Visual Studio going to continue to support .NET Framework 4.8?
Immo Landwerth Having
net5.0-windows
doesn’t mean we’re bringing all functionality from .NET Framework. In fact,we have said that we won’t. Specifically, we have said that we will not add support for AppDomains, remoting, Web Forms, WCF server, and Windows Workflow.Visual Studio will continue to support creating & maintaining .NET Framework applications, yes.
Lud Lelud Is the UNO platform considered in this roadmap?
Is UNO considered at all? or is it destined to stay on the side…?
UNO is pulling in right/same direction, or have i missed something?Yep not much of a comment, only questions… 🙂
Mohammad Prince quite well done
André Köhler I’m really happy with the direction .NET is taking.
Daren May Read moreThe way that compatibility works between libraries and TFMs has always been a little confusing to me. To give a concrete example, documented as a GitHub issue here, I have installed .NET5.0 RC1 and I create a console app and add a reference to the Microsoft.Azure.Devices.Client nuget package:
<code>
This creates a console app that targets: net5.0
The reference is added without warnings and issue, however when I try to use a method within the package, I get the following exception:<code>
When I look at the target types for the nuget package, I see this:
<code>
Naively, I expected this to work as .NET5.0 RC1...
Read lessThe way that compatibility works between libraries and TFMs has always been a little confusing to me. To give a concrete example, documented as a GitHub issuehere, I have installed .NET5.0 RC1 and I create a console app and add a reference to theMicrosoft.Azure.Devices.Client nuget package:
dotnet new consoledotnet add package Microsoft.Azure.Devices.Client
This creates a console app that targets: net5.0
The reference is added without warnings and issue, however when I try to use a method within the package, I get the following exception:Unhandled exception. System.NotSupportedException: Specified method is not supported. at Microsoft.Azure.Devices.Client.Common.ReadOnlyMergeDictionary`2.System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair>.get_Count()
When I look at the target types for the nuget package, I see this:
<PropertyGroup> <SupportsNetStandard20AndAbove Condition="'$(TargetFramework)' == 'netstandard2.1' Or '$(TargetFramework)' == 'netstandard2.0' Or '$(TargetFramework)' == 'net472'">true</SupportsNetStandard20AndAbove> </PropertyGroup>
Naively, I expected this to work as .NET5.0 RC1 is compatible withnetstandard2.1 andnetstandard2.0 (and I imagine it is a superset) yet it does not. Changing the TFM of the console app tonetcoreapp3.1 and rebuilding/running executes correctly.
How can I ensure at compile time that all of my dependencies will run without error?
Immo Landwerth Read moreYou're totally correct, this should just work. I consider this a bug in the Azure client library. I've filed a bug.
How can I ensure at compile time that all of my dependencies will run without error?
Well, you generally can't. TFMs are a tiny part of all the bugs a library can have. For example, if the author of the library never tested their code on Linux it might only work on Windows. There is no way to know this until statically.
Read lessYou’re totally correct, this should just work. I consider this a bug in the Azure client library. I’vefiled a bug.
How can I ensure at compile time that all of my dependencies will run without error?
Well, you generally can’t. TFMs are a tiny part of all the bugs a library can have. For example, if the author of the library never tested their code on Linux it might only work on Windows. There is no way to know this until statically.
Daren May Thanks for clarifying – I thought I was losing my mind!
Azad Abbasi We have released a new version of the SDK that should include the fix for the issue above.
We will appreciate if you could confirm that you no longer see this behavior.
Release NotesMicrosoft.Azure.Devices v1.27.2
Mirosoft.Azure.Devices.Client v1.31.2Thanks
AzadAzad Abbasi Bug is acknowledged and fix is in progress.
Matteo Spreafico How much changes (or what kind of impact) can we expect when upgrading to an LTS from the previous non-LTS? Or, to tell it in another way, does it makes sense to start big a project today on 5.0 planning to upgrade to 6.0 as soon as it will be available?
Matteo Spreafico No one monitoring comments here?
Immo Landwerth Sorry for the delay. We generally strive to keep the breaking changes to a minimum. You can expect that the lowest part of the stack (languages and BCL) have close to zero breaking changes while higher layers (ASP.NET Core, WinForms, WPF) will likely always have some. We’re committed to documenting all changes in the release notes.
Matteo Spreafico thank you very much Immo.
Michal Dobrodenka I don’t like the idea of c# 9 tied with net5.
I’m in IoT and my library has to support mono, because net5 doesn’t run on ARMv6.
Will mono support net5 in future? Or will net6 support more CPU architectures?
ColdFire Dragon So will there be a net5.0-macos to go along with the windows, android and ios?