Skip to content

Instantly share code, notes, and snippets.

@ufcpp
Created April 16, 2025 12:06
Show Gist options
  • Save ufcpp/bceebf1d0b0508e765d6288469208e1c to your computer and use it in GitHub Desktop.
Save ufcpp/bceebf1d0b0508e765d6288469208e1c to your computer and use it in GitHub Desktop.
OverloadResolutionPriority を使った制約違いオーバーロード(多引数)
using System.Runtime.CompilerServices;
// where が多いほど優先度を上げておかないと ambiguous エラー起こす。
// where の数が同じものは優先度も同じで大丈夫。
Console.WriteLine("* A");
A.M<C1, C1>();
A.M<C2, C1>();
A.M<C1, C2>();
A.M<C2, C2>();
A.M<C1, C1, C1>();
A.M<C2, C1, C1>();
A.M<C1, C2, C1>();
A.M<C1, C1, C2>();
A.M<C1, C2, C2>();
A.M<C2, C1, C2>();
A.M<C2, C2, C1>();
A.M<C2, C2, C2>();
// 型引数で渡す予定の型。
interface I;
class C1;
class C2 : I;
// 問題のメソッド。
static class A
{
[OverloadResolutionPriority(0)]
public static void M<T1, T2>() => Console.WriteLine("0");
[OverloadResolutionPriority(1)]
public static void M<T1, T2>(Tag<T1> _ = default) where T1 : I => Console.WriteLine("1");
[OverloadResolutionPriority(1)]
public static void M<T1, T2>(Tag<T2> _ = default) where T2 : I => Console.WriteLine("2");
[OverloadResolutionPriority(2)]
public static void M<T1, T2>(Tag<T1, T2> _ = default) where T1 : I where T2 : I => Console.WriteLine("1, 2");
[OverloadResolutionPriority(0)]
public static void M<T1, T2, T3>() => Console.WriteLine("0");
[OverloadResolutionPriority(1)]
public static void M<T1, T2, T3>(Tag<T1> _ = default) where T1 : I => Console.WriteLine("1");
[OverloadResolutionPriority(1)]
public static void M<T1, T2, T3>(Tag<T2> _ = default) where T2 : I => Console.WriteLine("2");
[OverloadResolutionPriority(1)]
public static void M<T1, T2, T3>(Tag<T3> _ = default) where T3 : I => Console.WriteLine("3");
[OverloadResolutionPriority(2)]
public static void M<T1, T2, T3>(Tag<T1, T2> _ = default) where T1 : I where T2 : I => Console.WriteLine("1, 2");
[OverloadResolutionPriority(2)]
public static void M<T1, T2, T3>(Tag<T2, T3> _ = default) where T2 : I where T3 : I => Console.WriteLine("2, 3");
[OverloadResolutionPriority(2)]
public static void M<T1, T2, T3>(Tag<T1, T3> _ = default) where T1 : I where T3 : I => Console.WriteLine("1, 3");
[OverloadResolutionPriority(3)]
public static void M<T1, T2, T3>(Tag<T1, T2, T3> _ = default) where T1 : I where T2 : I where T3 : I => Console.WriteLine("1, 2, 3");
}
// オーバーロードを増やすためのダミー型。
struct Tag<T>;
struct Tag<T1, T2>;
struct Tag<T1, T2, T3>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment