Skip to content

Instantly share code, notes, and snippets.

@gongdo
Created June 6, 2019 08:26
Show Gist options
  • Save gongdo/2316c2f36221537835aab191b69058a5 to your computer and use it in GitHub Desktop.
Save gongdo/2316c2f36221537835aab191b69058a5 to your computer and use it in GitHub Desktop.
Method return types: Non-nullable reference, nullable reference, struct and Nullable<struct>.
using System;
using System.Linq;
using Xunit;
namespace Something
{
public class NullableTest
{
public struct FooS
{
}
public class Foo
{
public Foo NonNullable() => new Foo();
public Foo? Nullable() => null;
public FooS Struct() => new FooS();
public FooS? NullableStruct() => null;
}
[Fact]
public void NonNullableReturnTypeMustHaveNullableFlagsOf1()
{
var sut = typeof(Foo).GetMethod(nameof(Foo.NonNullable));
Assert.Equal(typeof(Foo), sut.ReturnType);
var attr = sut.ReturnTypeCustomAttributes
.GetCustomAttributes(true)
.Single(a => a.GetType().Name.Equals("NullableAttribute"));
var flag = attr.GetType().GetField("NullableFlags").GetValue(attr);
Assert.Equal(new byte[] { 1 }, flag);
}
[Fact]
public void NullableReturnTypeMustHaveNullableFlagsOf2()
{
var sut = typeof(Foo).GetMethod(nameof(Foo.Nullable));
Assert.Equal(typeof(Foo?), sut.ReturnType);
var attr = sut.ReturnTypeCustomAttributes
.GetCustomAttributes(true)
.Single(a => a.GetType().Name.Equals("NullableAttribute"));
var flag = attr.GetType().GetField("NullableFlags").GetValue(attr);
Assert.Equal(new byte[] { 2 }, flag);
}
[Fact]
public void StructReturnTypeHaveNoNullableAttribute()
{
var sut = typeof(Foo).GetMethod(nameof(Foo.Struct));
Assert.Equal(typeof(FooS), sut.ReturnType);
var hasAttr = sut.ReturnTypeCustomAttributes
.GetCustomAttributes(true)
.Any(a => a.GetType().Name.Equals("NullableAttribute"));
Assert.False(hasAttr);
}
[Fact]
public void NullableStructReturnTypeIsNullableGenericDefinition()
{
var sut = typeof(Foo).GetMethod(nameof(Foo.NullableStruct));
Assert.Equal(typeof(FooS?), sut.ReturnType);
Assert.Equal(typeof(Nullable<>), sut.ReturnType.GetGenericTypeDefinition());
}
}
}
@gongdo
Copy link
Author

gongdo commented Jun 6, 2019

  • System.Runtime.CompilerServices.NullableAttribute Attribute will be created dynamically in each assemblies.
  • The attribute will be attached to the ReturnTypeCustomAttributes of all methods that returns reference type.
  • The attribute has NullableFlags field with type of byte[]. { 1 } for non-nullable reference, { 2 } for nullable reference.
  • Both struct and Nullable return type doesn't have the attribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment