Skip to content

Instantly share code, notes, and snippets.

@ufcpp
Created April 16, 2021 08:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ufcpp/ec4586dd9b0a343e72a97658c08c5126 to your computer and use it in GitHub Desktop.
Save ufcpp/ec4586dd9b0a343e72a97658c08c5126 to your computer and use it in GitHub Desktop.
covariance の解析、null 許容参照型の方がジェネリクスよりも賢い
#nullable enable
using System.Collections.Generic;
// nullability は out 引数でも variance が効く。
string notNull = "";
string? nullable = null;
A.In<string?>(notNull);
A.In<string?>(nullable);
A.In<string>(notNull);
A.In<string>(nullable); // ここと
A.Out<string?>(out notNull); // ここだけ警告。
A.Out<string?>(out nullable);
A.Out<string>(out notNull);
A.Out<string>(out nullable); // variance が利いてる。
// generics の variance は out 引数に対して働かない。
IEnumerable<string> str = null!;
IEnumerable<object> obj = null!;
A.In<IEnumerable<object>>(str);
A.In<IEnumerable<object>>(obj);
A.In<IEnumerable<string>>(str);
A.In<IEnumerable<string>>(obj); // ここと
A.Out<IEnumerable<object>>(out str); // ここがエラーになるのは variance 的に正しい。
A.Out<IEnumerable<object>>(out obj);
A.Out<IEnumerable<string>>(out str);
A.Out<IEnumerable<string>>(out obj); // これがエラーになるのは合理性ない(.NET の型システム都合の妥協)。
public class A
{
public static void In<T>(in T x) { }
public static void Out<T>(out T x) => x = default!;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment