Search code examples
c#attributesresharpergeneric-type-argument

Can ReSharper [CanBeNull] and [NotNull] attributes be applied to an Action or Func argument?


ReSharper has a suite of code annotations which are useful for explicitly expressing code intent that can be used by the IDE. Two of the most useful annotations are the [CanBeNull] and [NotNull] attributes, which can be used on Constructors, Properties, and Methods, like this:

[CanBeNull]
private Foo DoSomething([NotNull] string text)
{
    // ...
}

This is a long shot, but is there any way these attributes can be assigned to an Action or Func parameter?

I understand that the following code is illegal (because type arguments are not a valid target for attributes), but is there an alternative way of expressing this?

private void DoSomething(Action<[NotNull]string> processText)
{
    ///...
}

Solution

  • You can do this if you're willing to create a custom delegate type:

        delegate void TextProcessor([NotNull] string text);
    
        delegate void NullableTextProcessor([CanBeNull] string text);
    
        private void DoSomething([NotNull] TextProcessor processText)
        {
            // ...
        }
    
        private void DoSomethingNull([NotNull] NullableTextProcessor processText)
        {
            // ...
        }
    

    Delegates

    Unfortunately, CanBeNull doesn't seem to give warnings in lambda syntax:

    Calls

    But you might just want to wait for C# 8's nullable/non-nullable reference types.