Dynamic 如何访问匿名类型的属性?

Dynamic 如何访问匿名类型的属性?,dynamic,ironpython,invoke,anonymous-types,Dynamic,Ironpython,Invoke,Anonymous Types,考虑到这个IronPython脚本 def SensorEvent(d): print d print d.Message 。。。如何访问d的属性 SensorEvent方法的第一行已成功打印 {Message=blah blubb} 但是,第二行抛出一个异常: “f_anonymousType[str]”对象没有“Message”属性 解释 d是由C#方法调用提供的匿名类型的实例。我这样调用它: public static async void ExecutePyF

考虑到这个IronPython脚本

def SensorEvent(d):
    print d
    print d.Message
。。。如何访问
d
的属性

SensorEvent方法的第一行已成功打印

{Message=blah blubb}

但是,第二行抛出一个异常:

“f_anonymousType[str]”对象没有“Message”属性


解释

d
是由C#方法调用提供的匿名类型的实例。我这样调用它:

    public static async void ExecutePyFunc(string name, dynamic data)
    {
        try
        {
            var f = strategyScope.GetVariable<Action<object>>(name);
            if (f != null)
            {
                await Task.Run(() => f((object)data));
            }
        }
        catch (Exception x)
        {
            StaticLog("[Callback Exception] Fehler beim Ausführen einer Python Funktion: {0}", x.Message);
        }
    }
public静态异步void ExecutePyFunc(字符串名,动态数据)
{
尝试
{
var f=strategyScope.GetVariable(名称);
如果(f!=null)
{
等待任务。运行(()=>f((对象)数据));
}
}
捕获(异常x)
{
StaticLog(“[Callback Exception]Fehler beim Ausführen einer Python函数:{0}”,x.Message);
}
}

d是一本字典。像这样访问它:

d['Message']

d是一本字典。像这样访问它:

d['Message']

我使用DynamicObject的解决方案:我引入了一个类,该类通过反射复制匿名类型的属性,将匿名类型转换为已知类型(除了属性之外,我不需要其他任何东西,但可能还可以对其进行增强,以便与字段、方法和函数一起使用)

以下是我的想法:

public class IronPythonKnownType : DynamicObject
{
    public IronPythonKnownType(dynamic obj)
    {
        var properties = obj.GetType().GetProperties();
        foreach (PropertyInfo prop in properties)
        {
            var val = prop.GetValue(obj);
            this.Set(prop.Name, val);
        }
    }

    private Dictionary<string, object> _dict = new Dictionary<string, object>();
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (_dict.ContainsKey(binder.Name))
        {
            result = _dict[binder.Name];
            return true;
        }
        return base.TryGetMember(binder, out result);
    }

    private void Set(string name, object value)
    {
        _dict[name] = value;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _dict[binder.Name] = value;
        return true;
    }
}

没有得到提到的异常。

我使用DynamicObject的解决方案:我引入了一个类,通过反射复制匿名类型的属性,将其转换为已知类型(除了属性之外,我什么都不需要,但它可能还可以增强,以便与字段、方法和函数一起使用)

以下是我的想法:

public class IronPythonKnownType : DynamicObject
{
    public IronPythonKnownType(dynamic obj)
    {
        var properties = obj.GetType().GetProperties();
        foreach (PropertyInfo prop in properties)
        {
            var val = prop.GetValue(obj);
            this.Set(prop.Name, val);
        }
    }

    private Dictionary<string, object> _dict = new Dictionary<string, object>();
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (_dict.ContainsKey(binder.Name))
        {
            result = _dict[binder.Name];
            return true;
        }
        return base.TryGetMember(binder, out result);
    }

    private void Set(string name, object value)
    {
        _dict[name] = value;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _dict[binder.Name] = value;
        return true;
    }
}

没有得到提到的例外情况。

我明白了。谢谢有没有一种方法可以像对象一样访问它?您可以将python dict转换为对象。看起来它们都是在Python脚本中进行转换的。在调用之前,有没有一种方法可以在外部执行此操作?我希望Python代码尽可能简洁明了。如果您的C#obj被序列化为dict,您唯一能做的就是将其传递给JSON或其他东西,而不是对象,然后在另一端进行反序列化。如果是这样的话,最终,上面顶部链接中提到的Struct类实际上非常相似。我不知道你是否能得到你想要的东西。实际上,看看,尤其是
CreateInstance
方法。够干净吗?我明白了。谢谢有没有一种方法可以像对象一样访问它?您可以将python dict转换为对象。看起来它们都是在Python脚本中进行转换的。在调用之前,有没有一种方法可以在外部执行此操作?我希望Python代码尽可能简洁明了。如果您的C#obj被序列化为dict,您唯一能做的就是将其传递给JSON或其他东西,而不是对象,然后在另一端进行反序列化。如果是这样的话,最终,上面顶部链接中提到的Struct类实际上非常相似。我不知道你是否能得到你想要的东西。实际上,看看,尤其是
CreateInstance
方法。够干净吗?