はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【C#】C#13から登場した「OverloadResolutionPriority」を用いてオーバーロードの優先順位を指定する

はじめに

C#13で新しくSystem.Runtime.CompilerServices.OverloadResolutionPriorityAttributeが追加されました。

namespace System.Runtime.CompilerServices;

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class OverloadResolutionPriorityAttribute(int priority) : Attribute
{
    public int Priority => priority;
}

属性の意味・使い方はとてもシンプルなのですが、結構強力な属性なので紹介したいと思います。

概要&使い方

[OverloadResolutionPriority]を用いることでオーバーロード解決の優先順位を指定できます。

public static void Main(string[] args)
{
    // ReadOnlySpan
    M(1, 2, 3);
}

// 数字が大きい方が優先される
[OverloadResolutionPriority(2)]
public static void M(params ReadOnlySpan<int> s) => Console.WriteLine("ReadOnlySpan");
    
[OverloadResolutionPriority(1)]
public static void M(params Span<int> s) => Console.WriteLine("Span");
    
// OverloadResolutionPriorityを指定しない場合はデフォルト値0が適用される
public static void M(params int[] a) => Console.WriteLine("Array");

// 負の数もいける
[OverloadResolutionPriority(-1)]
public static void M(params List<int> l) => Console.WriteLine("List");

デフォルトが0であることと、数字が大きいほど優先されることさえ覚えておけばOKです。

恩恵を受けるケース

公式ドキュメントでも触れられていますが、割と恩恵を受けるのはライブラリを作成する人ですね。後方互換性を残しつつ、より優れたオーバーロードを追加した際には[OverloadResolutionPriority]を付与していくという流れになるのかなと。

ライブラリ作成者は、新しいより優れたメソッド オーバーロードを追加するときに、この属性を最後の手段として使用する必要があります。 ライブラリ作成者は、オーバーロードの解決より適切な方法の選択に与える影響について深く理解している必要があります。 そうしないと、予期しないエラーが発生する場合があります。

https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/attributes/general#overloadresolutionpriority-attribute