ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

オペレータオーバーロード

プログラミングC# p125

「6.2 他.NET言語への配慮」として、

C#には演算子オーバーロードする機能がありますが、厳密なことをいうと、CLRにはそういった機能はありません。VB.NETなど他.NET言語は演算子オーバーロードの機能を持たないのです。そのため、C#以外の言語からも利用するクラスを作る場合は、ユーザ定義の演算子と同じ効果が得られる代替メソッドを用意しておくことが重要です。

そういうもんなの?という疑問の元、検証してみました。

まず、VB.NETでは文字列の足し算すら出来ないのか?という疑問を解消。

Imports System

Class Test
        Public Shared Sub Main
                Console.WriteLine("Hello, " + "VB.NET")
        End Sub
End Class

結果はこう。

Hello, VB.NET

普通に動きます。


じゃあ、C#でオペレータオーバーロードしてみる。
長方形を表すクラスRectangleを定義。フィールドとしてxとyを持っている。
operator +を呼ぶと、二つのRectangleのそれぞれのフィールドを足し合わせて新しいRectangleオブジェクトを生成する。

using System;

namespace rectangle
{
        public class Rectangle
        {
                private int x;
                private int y;

                public Rectangle(int x, int y)
                {
                        this.x = x;
                        this.y = y;
                }

                public int X
                {
                        get {return x;}
                        set {x = value;}
                }

                public int Y
                {
                        get {return y;}
                        set {y = value;}
                }

                public override string ToString()
                {
                        return "x = " + this.x + ", y = " + this.y;
                }

                public static Rectangle operator +(Rectangle r1, Rectangle r2)
                {
                        return new Rectangle(r1.X + r2.X, r1.Y + r2.Y);
                }

                public static void Main(string[] args)
                {
                        Rectangle r1 = new Rectangle(3, 5);
                        Rectangle r2 = new Rectangle(4, 6);
                        Console.WriteLine("r1 : {0}", r1);
                        Console.WriteLine("r2 : {0}", r2);

                        Rectangle r3 = r1 + r2;
                        Console.WriteLine("r3 : {0}", r3);
                }
        }
}

この結果はこう。

r1 : x = 3, y = 5
r2 : x = 4, y = 6
r3 : x = 7, y = 11

これまた普通に動く。


じゃあ、これをVB.NETから呼んで見ることにする。

まず、DLLを作成する。

csc /T:library Rectangle.cs

呼び側のVB.NETソースを書く。

Imports System
Imports rectangle

class CallRectangle
        Public Shared Sub Main()
                Dim r1 As New rectangle.Rectangle(3, 4)
                Dim r2 As New rectangle.Rectangle(4, 5)
                Dim r3 As rectangle.Rectangle

                r3 = r1 + r2
                Console.WriteLine("r3 : {0}", r3)
        End Sub
end class

コンパイルする。

vbc /R:Rectangle.dll CallRectangle.vb

実行した結果。

r3 : x = 7, y = 9

というわけで、別に配慮なんか要らないような気がします。
時代は進歩したのかしら?