What does [param: NotNull] mean in C#?

C#

C# Problem Overview


In Entity Framework's source code (link) I found this line:

public virtual IRelationalTransaction Transaction 
{ get; [param: NotNull] protected set; }

The [param: NotNull] part looks very strange to me. Any idea what kind of a C# syntax is this? I'm familiar with attributes and param but not this combination.

The definition of NotNull is this:

[AttributeUsage(
    AttributeTargets.Method | AttributeTargets.Parameter |
    AttributeTargets.Property | AttributeTargets.Delegate |
    AttributeTargets.Field)]
internal sealed class NotNullAttribute : Attribute
{
}

Which I expected to be used simply as [NotNull] but what is param doing here?

C# Solutions


Solution 1 - C#

When you mark method with NotNull it means, that method returns not null object:

[NotNull]
public object Get()
{
    return null; //error
}

When you mark setter it does the same - setter returns not null (because .net converts properties to get and set methods).

public virtual IRelationalTransaction Transaction { get; [NotNull] protected set; }

Equals to:

[NotNull] 
public virtual void set_Transaction(IRelationalTransaction value) { ... }

So, you need to add param: to point, that "i mean - parameter of setter is not null, not a result of set-method":

public virtual IRelationalTransaction Transaction { get; [param: NotNull] protected set; }

Equals to:

public virtual void set_Transaction([NotNull] IRelationalTransaction value) { ... }

Solution 2 - C#

param: is the attribute target. See: Attribute specification

The attribute target can be one of these:

>assembly, module, field, event, method, param, property, return, type

So [param: NotNull] means that the NotNullAttribute applies to the value parameter of the setter. It is necessary to specify the target here, since the value parameter does not appear as a method parameter explicitly.


A common use of the attribute-target is to specify the InternalsVisibleToAttribute in order to make types and members declared as internal visible to unit test projects.

[assembly:InternalsVisibleTo("UnitTestProject")]

The assembly does not appear as a language construct, therefore the attribute-target assembly is the only way to specify an attribute for the assembly. Btw: It can be specified in any source code file.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionel_shayanView Question on Stackoverflow
Solution 1 - C#BacksView Answer on Stackoverflow
Solution 2 - C#Olivier Jacot-DescombesView Answer on Stackoverflow