2017-01-14 12 views
6

誰かこの本当に奇妙な観測を教えてもらえますか?IronPythonスクリプトの中からlambdaを使ってRx拡張メソッドを呼び出すことはできますか?

私はIronPython内部からRx拡張メソッドを呼び出そうとしていましたが、それは単に不可能になっています。私はこの簡単な例に煮詰めました:

import clr 
clr.AddReference("System.Core") 
from System.Linq import Enumerable 

def process(value): 
    return Enumerable.Select(value, lambda x:x) 

この場合、通常のLINQから始めます。 process関数を配列やその他のIEnumerableオブジェクトを持つ私のホスティング環境から呼び出すと、まったく問題なく動作します。私はIObservable対象とprocess機能、醜いとのコールがクラッシュを呼び出す場合、この場合、

import clr 
clr.AddReference("System.Reactive.Linq") 
from System.Reactive.Linq import Observable 

def process(value): 
    return Observable.Select(value, lambda x:x) 

だから、私は単にObservable拡張そうのようなメソッドを使用するように参照を交換してみましたエラーメッセージ:

expected IObservable[object], got Select[int, int]

は、誰もがこのような何かを思いついていますか?私は何かを逃したか? Observableが存在しないラムダ代理人とEnumerableの作業を行う特別なケースがありますか?私はここで完全に困惑していることを認めなければならない。ところで

は、ちょうど健全性チェックとして、次の例では、正常に動作します:

import clr 
clr.AddReference("System.Reactive.Linq") 
from System.Reactive.Linq import Observable 

def process(value): 
    return Observable.Sum(value) 

私はそこにそれを残すためにちょうどそれが明確な問題が実際にメソッド呼び出しであることを確認したかったですObservable.Select

+0

IronPythonリポジトリに[issue](https://github.com/IronLanguages/main/issues/1564)を追加しました。私はこれがIronPythonのメソッドコール解決のより一般的なバグであると考えていますが、この問題についてのさらなる洞察に感謝するでしょう。 – glopes

答えて

2

私が疑う問題の一部は、メソッドがオーバーロードされていることです。 IronPythonランタイムは、使用するのに最適なオーバーロードを見つけるために最善を尽くしますが、ときどき間違ってしまうことがあります。オーバーロードの曖昧さを解消するためには、支援が必要な場合があります。

エラーメッセージから、IObservable<int>で呼び出そうとしているようです。ここでは、過負荷の解決が失敗していると思われ、Observable.Select<object, object>()と呼びます。あなたは、使用したいオーバーロードにいくつかのヒントを提供する必要があります。

def process(value): 
    return Observable.Select[int,int](value, Func[int,int](lambda x:x)) 
+0

これはうまくいきました。実際この場合、ジェネリックメソッドの明示的な型は必要ありません。明示的にラムダを入力するだけで十分です。問題は、メソッドが全く同じオーバーロードを持つEnumerableクラス(たとえば、引数が異なるラムダ)で必要でない理由です。 – glopes

+1

もし私が推測しなければならない場合、継承された観測可能なインスタンスは、おそらく競合する多くのインタフェースを実装し、ラムダがどの型を取るべきかを決める方法を知らなかったケースを打ち負かすに違いありません。ほとんどのコレクションは簡単なので、最適なオーバーロードを見つける方が簡単です。私は今これを確認することはできませんが、どこかに 'object'を使用する明示的に実装されたインターフェースがあり、それを使用しているのかもしれません。 –

+0

実際、IronPythonは、たとえ「Enumerable.Select」の場合でも、LINQのようなラムダの型を実際に推論することができないという明白な事実を認識しています。 Pythonが本質的に動的な言語であることを考えると、セレクタの本体は原則として毎回何かを返すことができるので、妥当な唯一の戻り値の型は 'object'です。LINQをこのようにスクリプト化するのは大変です。 – glopes

関連する問題