C#のオーバーロードが正しくない事がある

投稿者:onichan 投稿日:2024/04/21(Sun) 22:52:48 No.2371

いつもお世話になっております。

object[]またはdynamic[]を引数に取るメソッドに、プロデルで型固定された配列を入れようとすると、期待通りのオーバーロードが選択されない事があるようです。

```プログラム例(cs)
using System.Linq;
using Produire;

namespace ClassLibrary1
{
public class Class1 : IProduireGlobalClass
{
[自分で]public object[] スライス([を] object[] 内容) => 内容.Take(5).ToArray(); //要素型を問わず配列はこちらのメソッドで受け付けたい
[自分で]public string スライス([を] string 内容) => 内容.Substring(0, 5);
}
}
```

```プログラム例(rdr)
「(省略)\ClassLibrary1.dll」を利用
{1,2,3,4,5,6}をスライスして表示 //{1,2,3,4,5}
「123456」をスライスして表示 //12345

【A:整数の配列】={1,2,3,4,5,6}
Aをスライスしたものの種類名を表示 //object[]側のメソッドが呼ばれてほしいがstring側が呼ばれる
```

状況:Pythonのスライサーを再現するメソッドを作っている際に発覚しました。

プロデルバージョン:1.9.1209〜1.9.1239
C#7.3 .NET Framework 4.8.9232.0 コンパイラ4.9.0-3.24121.1(a98c90d5)

よろしくお願いいたします。

Re: C#のオーバーロードが正しくない事がある

投稿者:ゆうと 投稿日:2024/04/26(Fri) 03:12:00 No.2372

こんにちは、お世話になっております。

動作等を再現させて検討しましたが
string型とobject[]型のオーバロードの手順決定できない挙動については
仕様とさせてください。
(エラーとならずにどちらかが実行されてしまう挙動はバグです)

理由としては、
整数の配列を、C#の引数に渡す際に、string型でもobject[]型でも、値変換が必要となります。
このケースのように、助詞が一致する場合には、どちらの引数も値変換が必要な点は同じですので、どちら一方に決めることができません。

同じ配列ならobject[]型が選択されることを期待しますが、要素の型を整数からobject型に変換する必要があるため「変換が必要な手順呼び出し」と判断されます。

対策としてはC#側でint[]の値に対するオーバロードを定義するか、次のように「←」によるキャストを指定してください。この場合は正しく手順が決まります。

----
【A:整数の配列】={1,2,3,4,5,6}
(A←配列)の種類名を表示
----

参考にしてください。

解決しました。

投稿者:onichan 投稿日:2024/04/26(Fri) 09:04:01 No.2373

お世話になっております。

内容について承知いたしました。
(キャスト構文ないと思ってたので個人的に嬉しいです)

ご確認いただきありがとうございます。
今後ともよろしくお願いいたします。

▲ページの先頭へ

- WebForum -