ufcpp/UfcppSample

「オーバーロード解決優先度」ページの配列を引数に取るオーバーロードが優先されている問題の修正

Closed this issue · 3 comments

https://ufcpp.net/blog/2024/2/overload-resolution-priority/
ページ下部の OverloadResolutionPriority 属性に関する記述の部分です。

C.M(ReadOnlySpan<int>) の方が選ばれるようにしたいため、配列のオーバーロードの方の優先度を -1 にすべきかと思われます。

int[] x = [1, 2, 3];

// ReadOnlySpan<int> の方が選ばれるようになる予定。
C.M(x);

public class C
{
-    // 優先度を上げたければ priority の数字を増やす。
+    // 優先度を下げたければ priority の数字を減らす。
-    [OverloadResolutionPriority(1)]
+    [OverloadResolutionPriority(-1)]
    public static void M(int[] x) { }

-    // 逆にこっちに priority = -1 とかを与えて優先度を下げるとかでも OK。
+    // 逆にこっちに priority = 1 とかを与えて優先度を上げるとかでも OK。
    public static void M(ReadOnlySpan<int> x) { }
}

public class OverloadResolutionPriorityAttribute(int priority) : Attribute
{
    public int Priority { get; } = priority;
}

以下は個人的に思ったことです。

  • あるメソッドの優先度を上げる使い方より、下げる使い方が無難?でしょうか。
    • 後から追加するオーバーロードにも全て OverloadResolutionPriority 属性を付け、同じ優先度を設定する必要があります。
    • もし属性をつけ忘れた場合、追加したメソッドは呼ばれることはないのですが、コンパイルエラーにはならず見逃してしまう気がします。
    • 呼び出し側のメソッドにマウスカーソルを合わせるとどのオーバーロードが呼ばれているか確認できますが、目視が必要です。
  • 自動テストでどのオーバーロードが呼ばれているか確認するのは、なんか大変そうな気がします。
  • この属性を標準ライブラリにペタペタ貼り付けていく作業はなんか・・・。自動化できそうではあります。

元の提案が「上げる方」から書いてるんですよね。

それに合わせたけども M(int[] x)M(ReadOnlySpan<int> x) の順番逆だった… というのがミスの原因ではあるんですが。

数字を増やす方、「元のライブラリはいじらずに、高プライオリティの拡張メソッドを足す」とかに使えるんですかね?
それがいいのか悪いのか… できるようになるのかどうか。

まあ、順序を入れ替え。