C#

in 引数のOperator overloadとdynamicの相性が悪い件

TL;DR

dynamic経由で呼べなかった

どーいうことか

以下のような構造体をこさえたとして

public struct UseValue
{
    public int Value;

    public UseValue(int value)=>Value = value;

    public static UseValue operator +(UseValue a, UseValue b) => new UseValue(a.Value + b.Value);
}


これを、以下のように使ったとする

static void Main(string[] args)
{
    dynamic a = new UseValue(10);
    dynamic b = new UseValue(20);

    var ans = a + b;
    Console.WriteLine(ans.Value);
}


このとき、何の問題も無く+は動的に解決されて、30が表示される。

他方、C#7.2から演算子オーバーロードにもin 引数の利用が可能になったので、以下のように書いてみる。

public struct UseReadonlyRef
{
    public int Value;

    public UseReadonlyRef(int value) => Value = value;

    public static UseReadonlyRef operator +(in UseReadonlyRef a,in UseReadonlyRef b) => new UseReadonlyRef(a.Value + b.Value);

}

で、こいつを同様に呼び出す

static void Main(string[] args)
{
    dynamic a = new UseReadonlyRef(10);
    dynamic b = new UseReadonlyRef(20);

    var ans = a + b;
    Console.WriteLine(ans.Value);
}


このとき、var ans=a+bのステートメントで、RuntimeBinderExceptionが発生する。

恐らく、ランタイムバインダがin引数の演算子オーバーロードに対応していないためと思う。
これが、将来的に修正されるのかどうかは不明ですが、結構引っかかりやすいかなぁと思ってまとめました。