Closed andrewvk closed 3 years ago
One more interesting point. R# automatically removes its own CanBeNull markup when adding "?" to a type. @NN---
I paid attention to that:) As I said my concern is old ReSharper versions without good NRT support.
@andrewvk So, do we agree that all ReSharper nullability attributes will be replaced with .NET nullability attributes ?
@andrewvk Can we merge what we have now ?
There is some issue with nullability and autogenerated code. By default, C# compiler treat all generated code as #nullable disabled, regardless of project settings. In that case you should specify #nullable enabled explicitly. I fixed this in base T4 template, but did not rerun all templates. So, after I did it we still have hundreds of nullability warnings and errors (see last commit).
Ok. I can fix that too. There is some problem with build time limit . Is there any solution for this ?
If there is one, I don't know it :(
I think GitHub actions can handle this. Need to try.
@andrewvk in my project I added NAssert.NotNull which tells compiler to make variable non nullable and avoid useless ! . Do you think it worth adding it?
Can you explain in more detail what you mean by that? In any case, using ! in most cases is definitely not the best option.
This assertion makes this code compiling
string? f();
void g(string) {}
string? a = f();
NAssert.NotNull(a);
// a here is not null
g(a); // OK
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
namespace Tests
{
public static class NAssert
{
#pragma warning disable CS8777 // Parameter must have a non-null value when exiting.
// The warning is due to fact we do not check for null and throw directly.
#region NotNull
/// <summary>
/// Verifies that the object that is passed in is not equal to <see langword="null" />. Returns without throwing an
/// exception when inside a multiple assert block.
/// </summary>
/// <param name="anObject">The object that is to be tested</param>
/// <param name="message">The message to display in case of failure</param>
/// <param name="args">Array of objects to be used in formatting the message</param>
public static void NotNull([NotNull] object? anObject, string message, params object?[]? args)
{
Assert.NotNull(anObject, message, args);
}
/// <summary>
/// Verifies that the object that is passed in is not equal to <see langword="null" />. Returns without throwing an
/// exception when inside a multiple assert block.
/// </summary>
/// <param name="anObject">The object that is to be tested</param>
public static void NotNull([NotNull] object? anObject)
{
Assert.NotNull(anObject);
}
#endregion
#pragma warning restore CS8777 // Parameter must have a non-null value when exiting.
}
}
Btw, IDictionary doesn't require "TKey : notnull" according to sources. https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/IDictionary.cs
It means adding this constraint is not correct.
You mean that NUnit still doesn't have a NotNull attribute markup? Yeah, that's pretty weird. Of course, in this case it's worth adding your own variant.
Yeah. I tried to reproduce this in a separate project but everything compiled. Probably it requires this constraint only for specific framework. Currently everything compiles but not in appveyor:( I’ll check how to improve it.
Core 3.0 library Core 5.0 library Shall we try to hide it under a compiler directive?
`#if NETCOREAPP3_1 where TKey : notnull
Build OK
It is better to not introduce additional constraint if possble
Fixed recursion and now the build works :) @andrewvk Is there anything left in PR ?
Feel free to apply changes from previous PR.