Last active
April 18, 2025 01:35
-
-
Save ufcpp/2d042620f5349b89afceb66b8d3eae51 to your computer and use it in GitHub Desktop.
OverloadResolutionPriority を使った制約違いオーバーロード
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Runtime.CompilerServices; | |
Ex.M<C1>(); // where class | |
Ex.M<S1>(); // where struct | |
Ex.M<C2>(); // where class, I | |
Ex.M<S2>(); // where struct, I | |
Ex.M<I>(); // これは class, I に行く。インターフェイスは参照型なので。 | |
static void M1<T>() => Ex.M<T>(); // none | |
static void M2<T>() where T : I => Ex.M<T>(); // where I | |
// 型引数で渡す予定の型。 | |
interface I; | |
class C1; | |
struct S1; | |
class C2 : I; | |
struct S2 : I; | |
// 制約違いオーバーロード。 | |
static class Ex | |
{ | |
[OverloadResolutionPriority(-2)] | |
public static void M<T>() => Console.WriteLine("none"); | |
[OverloadResolutionPriority(-1)] | |
public static void M<T>(Tag<Struct> _ = default) where T : struct => Console.WriteLine("struct"); | |
[OverloadResolutionPriority(-1)] | |
public static void M<T>(Tag<Class> _ = default) where T : class => Console.WriteLine("class"); | |
[OverloadResolutionPriority(-1)] | |
public static void M<T>(Tag<I> _ = default) where T : I => Console.WriteLine("I"); | |
[OverloadResolutionPriority(0)] | |
public static void M<T>(Tag<Struct, I> _ = default) where T : struct, I => Console.WriteLine("struct : I"); | |
[OverloadResolutionPriority(0)] | |
public static void M<T>(Tag<Class, I> _ = default) where T : class, I => Console.WriteLine("class : I"); | |
} | |
// オーバーロードを増やすためのダミー型。 | |
struct Struct; | |
struct Class; | |
struct Tag<T1>; | |
struct Tag<T1, T2>; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Runtime.CompilerServices; | |
Ex.M<O>(); // class | |
Ex.M<A>(); // class, IA | |
Ex.M<B>(); // class, IB | |
Ex.M<AB>(); // class, IA, IB | |
Ex.M<Os>(); // struct | |
Ex.M<As>(); // struct, IA | |
Ex.M<Bs>(); // struct, IB | |
Ex.M<ABs>(); // struct, IA, IB | |
// インターフェイスは参照型なので: | |
Ex.M<IA>(); // これは class, IA に行く。 | |
Ex.M<IB>(); // これは class, IB に行く。 | |
Unconstrained.O<O>(); // none | |
Unconstrained.A<A>(); // IA | |
Unconstrained.B<B>(); // IB | |
Unconstrained.AB<AB>(); // IA, IB | |
class Unconstrained | |
{ | |
public static void O<T>() => Ex.M<T>(); | |
public static void A<T>() where T : IA => Ex.M<T>(); | |
public static void B<T>() where T : IB => Ex.M<T>(); | |
public static void AB<T>() where T : IA, IB => Ex.M<T>(); | |
} | |
// 型引数で渡す予定の型。 | |
interface IA; | |
interface IB; | |
class O; | |
class A : IA; | |
class B : IB; | |
class AB : IA, IB; | |
struct Os; | |
struct As : IA; | |
struct Bs : IB; | |
struct ABs : IA, IB; | |
// 制約違いオーバーロード。 | |
// OverloadResolutionPriority の値は「制約の数」にしとく。 | |
static class Ex | |
{ | |
public static void M<T>() => Console.WriteLine("none"); | |
[OverloadResolutionPriority(1)] | |
public static void M<T>(Tag<Struct> _ = default) where T : struct => Console.WriteLine("struct"); | |
[OverloadResolutionPriority(1)] | |
public static void M<T>(Tag<Class> _ = default) where T : class => Console.WriteLine("class"); | |
[OverloadResolutionPriority(1)] | |
public static void M<T>(Tag<IA> _ = default) where T : IA => Console.WriteLine("IA"); | |
[OverloadResolutionPriority(1)] | |
public static void M<T>(Tag<IB> _ = default) where T : IB => Console.WriteLine("IB"); | |
[OverloadResolutionPriority(2)] | |
public static void M<T>(Tag<Struct, IA> _ = default) where T : struct, IA => Console.WriteLine("struct, IA"); | |
[OverloadResolutionPriority(2)] | |
public static void M<T>(Tag<Class, IA> _ = default) where T : class, IA => Console.WriteLine("class, IA"); | |
[OverloadResolutionPriority(2)] | |
public static void M<T>(Tag<Struct, IB> _ = default) where T : struct, IB => Console.WriteLine("struct, IB"); | |
[OverloadResolutionPriority(2)] | |
public static void M<T>(Tag<Class, IB> _ = default) where T : class, IB => Console.WriteLine("class, IB"); | |
[OverloadResolutionPriority(2)] | |
public static void M<T>(Tag<IA, IB> _ = default) where T : IA, IB => Console.WriteLine("IA, IB"); | |
[OverloadResolutionPriority(3)] | |
public static void M<T>(Tag<Struct, IA, IB> _ = default) where T : struct, IA, IB => Console.WriteLine("struct, IA, IB"); | |
[OverloadResolutionPriority(3)] | |
public static void M<T>(Tag<Class, IA, IB> _ = default) where T : class, IA, IB => Console.WriteLine("class, IA, IB"); | |
} | |
// オーバーロードを増やすためのダミー型。 | |
struct Struct; | |
struct Class; | |
struct Tag<T1>; | |
struct Tag<T1, T2>; | |
struct Tag<T1, T2, T3>; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Runtime.CompilerServices; | |
Ex.M<O>(); | |
Ex.M<A>(); | |
Ex.M<B>(); | |
Ex.M<AB>(); | |
// 型引数で渡す予定の型。 | |
interface IA; | |
interface IB; | |
class O; | |
class A : IA; | |
class B : IB; | |
class AB : IA, IB; | |
// 制約違いオーバーロード。 | |
static class Ex | |
{ | |
[OverloadResolutionPriority(-2)] | |
public static void M<T>() => Console.WriteLine("O"); | |
[OverloadResolutionPriority(-1)] | |
public static void M<T>(Tag<IA> _ = default) where T : IA => Console.WriteLine("A"); | |
[OverloadResolutionPriority(-1)] | |
public static void M<T>(Tag<IB> _ = default) where T : IB => Console.WriteLine("B"); | |
[OverloadResolutionPriority(0)] | |
public static void M<T>(Tag<IA, IB> _ = default) where T : IA, IB => Console.WriteLine("A, B"); | |
} | |
// オーバーロードを増やすためのダミー型。 | |
struct Tag<T1>; | |
struct Tag<T1, T2>; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment