Framework defines can easily break code
See original GitHub issueWith #309 we’ve added an implicit define based on the target framework, which is super useful for customers when using conditional compilation.
Unfortunately, this makes it extremely easy to write code that breaks during retargeting. Let’s say I’m in a .NET Standard project and I’d like to add a code path that uses some new feature in .NET Standard 2.1, so I multi-target for .NET Standard 2.0 and .NET Standard 2.1. The code would look as follows:
public void SomeMethod()
{
#if NETSTANDARD2_1
// Write some code that uses Span<T>
#else
// Write fallback logic
#endif
}
Fast forward a year. Now I’d like to add some logic that can light-up on .NET Standard 2.2. So in a different area in my code I’m writing this:
public void SomeOtherMethod()
{
#if NETSTANDARD2_2
// Write some code that uses some new feature in .NET Standard 2.2
#else
// Write fallback logic
#endif
}
The code will compile just fine and everything looks dandy until you realize that your .NET Standard 2.1 binary no longer uses Span<T>
in SomeMethod()
but emitted the fallback logic.
Ideally, we’d want to write code like this:
public void SomeMethod()
{
#if NETSTANDARD >= 2.1
// Write some code that uses Span<T>
#else
// Write fallback logic
#endif
}
Which C# doesn’t support (and likely never will). However, we could instead change the SDK to define more symbols, such as:
public void SomeMethod()
{
#if NETSTANDARD2_1_OR_HIGHER
// Write some code that uses Span<T>
#else
// Write fallback logic
#endif
}
The _OR_HIGHER
symbols would all be defined.
Thoughts?
Issue Analytics
- State:
- Created 4 years ago
- Reactions:13
- Comments:13 (8 by maintainers)
Top GitHub Comments
If we’re pushing for a C# change it’s worth pointing out numeric symbols won’t work for cases where we have three digit version numbers (
net > 4.5.1
). MSBuild has this problem today where two digits end up being compared how you would expect while three digits are ending up being a string comparison and thus 4.5.10 isn’t considered larger than 4.5.9. Oops.$([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.1'))
should work.