Как передать лямбда-выражение в конструктор C # из скрипта IronPython? - PullRequest
5 голосов
/ 29 апреля 2009

Я интегрирую движок скриптинга IronPython в мой C # raytracer, который до сих пор был легким, хотя я совершенно не знаком с Python. Однако есть одна особенность, с которой мне нужна помощь. У меня есть класс C #, который определяет конструктор, как это:

public CameraAnimation(Action<Camera, float> animation)

В C # я бы описал это так:

var camAnimation = new CameraAnimation((camera, time) => camera.Position += new Vector(1, 0, 0));

Я не могу понять, как сделать подобное назначение для объекта Action в IronPython, так как будет выглядеть синтаксис Python?

1 Ответ

2 голосов
/ 29 апреля 2009

Предполагая, что я истолковал это право, и Action является универсальным делегатом, ниже работает (заглушки, которые я использовал, включены).

Python:

import clr
clr.AddReference("IronPythonDelegates")

import IronPythonDelegates

def camActionPy(camera, time):
  print "Camera: " + str(camera) + ", time: " + str(time)

IronPythonDelegates.CameraAnimation(camActionPy);

CSharp:

namespace IronPythonDelegates
{
    public class Camera{}

    public class CameraAnimation
    {
    private System.Action<Camera, float> animation;

    public CameraAnimation(System.Action<Camera, float> animation)
    {
        this.animation = animation;
        this.animation(new Camera(), 1.5f);
    }
    }
 }

Я исправил вышесказанное, чтобы использовать System.Action, и он больше не требует явного отражения. Хотя это немного странно. По какой-то причине я мог бы создать созданный пользователем делегат, например:

explicitTestAction = IronPythonDelegates.TestAction[IronPythonDelegates.Camera, System.Single](camActionPy);
IronPythonDelegates.CameraAnimation(explicitTestAction);

но не смог сделать это с System.Action. Например. с

explicitSystemAction = System.Action[IronPythonDelegates.Camera, System.Single](camActionPy)
IronPythonDelegates.CameraAnimation(explicitSystemAction);

licitSystemAction имеет значение null. TestAction было просто определено как:

public delegate void TestAction<T1, T2>(T1 one, T2 two);

Но, к счастью, в любом случае это нормально:

CameraAnimation(System.Action) 

или

CameraAnimation(TestAction)

хотя по какой-то причине я не помню, чтобы это работало, когда я впервые попробовал ...

...