I have read the following article about nullable reference analysis in C# 8 not long ago: https://www.meziantou.net/csharp-8-nullable-reference-types.htm
The post-condition attributes are particularly interesting to me. Recently I have encountered a situation where it might be useful to apply MemberNotNull
attribute. However, unexpectedly I can't find MemberNotNull
and MemberNotNullWhen
public attributes in the .Net core 3.1. However, I can see a number of internal attributes declared in .net core:
https://source.dot.net/#q=MemberNotNull
Are there any substitutions in .net core for these attributes. Do I have to use .net 5 to use them?
You can reference Nullable package. It will do basically the same as you did with copy-paste. Think that's the best way to backport these attributes to pre .net50 sdks.
I tried to copy declarations of both attributes to my source code but it didn't help when I declared attributes in my custom namespace. However if I declare them in System.Diagnostics.CodeAnalysis
namespace like this then it works:
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public sealed class MemberNotNullWhenAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
/// <param name="member">
/// The field or property member that is promised to be not-null.
/// </param>
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new[] { member };
}
/// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
/// <param name="members">
/// The list of field and property members that are promised to be not-null.
/// </param>
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
/// <summary>Gets the return value condition.</summary>
public bool ReturnValue { get; }
/// <summary>Gets field or property member names.</summary>
public string[] Members { get; }
}
}
And Roslyn removes the displayed warning for possible null dereference. However, instead I receive the following error:
Error CS8652: The feature 'MemberNotNull attribute' is currently in Preview and unsupported. To use Preview features, use the 'preview' language version.
So it seems I can at least switch to the preview language version with this approach. But I would like to avoid such hacks, so if there is a better solution please provide it and I will mark it as an accepted answer.
EDIT: To avoid some confusion expressed in the comments - this answer allows to use MemberNotNullWhen
attribute without compile time error. Just add
<LangVersion>preview</LangVersion>
to your project file.
If you do not want to upgrade your framework version, or backport support for [MemberNotNull]
from .NET 5, you can instead initialize the relevant fields using the null forgiving operator as a workaround.
For example, if you have a non-nullable field _myField
that is initialized in the method Init()
, you can add write the following in your constructor to remove the warning about a non-null value when exiting the constructor.
_myField = null!;
InitFields();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With