読者です 読者をやめる 読者になる 読者になる

IronPythonとC#の連携

IronPython C#

C#で作ったライブラリをIronPythonから呼び出して遊んでみた。

Pythonを触るのは始めてということもあり、色んな所ではまったのでちょっとメモしておく。

文字列配列の渡し方

まずは、IronPythonからC#に文字列配列を渡すところが上手く動作しなかった。
どうやら、C#側で引数を受け取るときには、String[]やListではなく、IListにする必要があるみたい。
以下が動作したコード。

// C#のコード
using System;
using System.Collections.Generic;

namespace Example
{
    public class A
    {
        public void P(IList<String> msg)
        {
            foreach (String m in msg)
            {
                Console.WriteLine(m);
            }
        }
    }
}
# IronPythonのコード
import sys
import Example

msg = ["hoge", "fuga"]
a = Example.A()
a.P(msg)

そういえば、プログラミングMicrosoft .NET Framework 第2版 (マイクロソフト公式解説書)にも、引数はできるだけ汎用的な型にせよって書いてあったなぁ。
IListにしておけば、String[]もListも受け取ることができて汎用的でよいですね。

ジェネリッククラス

次は、C#で定義したジェネリッククラスをIronPythonから利用する方法です。
IronPythonでは、"[型パラメータ]"で指定するんですね。

// C#のコード
using System;
using System.Collections.Generic;

namespace Example
{
    public class B<T>
    {
        public B(T data)
        {
            Console.WriteLine(data.ToString());
        }
    }
}
# IronPythonのコード
import sys
import Example

b = Example.B[long](123)

ジェネリックメソッド

次は、ジェネリックメソッド。
始めは、型パラメータを省略して呼び出していたんだけど、それだと"型パラメータを指定してください"との例外が発生した。
どうやらC#のように型推論はできないみたいです。

// C#のコード
using System;
using System.Collections.Generic;

namespace Example
{
    public class C
    {
        public void M<T>(T data)
        {
            Console.WriteLine(data.ToString());
        }
    }
}
# IronPythonのコード
import sys
import Example

c = Example.C()
c.M[long](123)

型パラメータを2つにした場合

型パラメータを2つにして、ジェネリックメソッドを呼び出してみると上手く動かない。

// C#のコード
using System;
using System.Collections.Generic;

namespace Example
{
    public class D
    {
        public void M<T1, T2>(T1 data1, T2 data2)
        {
            Console.WriteLine(data1.ToString() + ":" + data2.ToString());
        }
    }
}
# IronPythonのコード
import sys
import Example

d = Example.D()
d.M[long,long](123,456)

こんな↓例外が発生してしまいます・・・

IronPython.Runtime.Exceptions.ArgumentTypeException
"__getitem__() takes exactly 1 argument (1 given)"

型パラメータが2つあるジェネリッククラスは問題なく動作するのに、ジェネリックメソッドだと動作しないなんて、なんでだろう?