C# 4.0:将动态转换为静态

2024-03-05

这是一个与我问的另一个问题相关的分支问题here https://stackoverflow.com/questions/2783616/net-4-0-dynamic-object-used-statically/。我将其分开,因为这实际上是一个子问题:

我在投射类型对象时遇到困难dynamic到另一个(已知的)静态类型。

我有一个ironPython 脚本正在执行此操作:

import clr
clr.AddReference("System")
from System import *

def GetBclUri():
    return Uri("http://google.com")

请注意,这只是新建 BCL System.Uri 类型并返回它. So 我知道静态类型返回的对象。

现在在 C# 领域,我正在更新托管内容的脚本并调用此 getter 来返回 Uri 对象:

dynamic uri = scriptEngine.GetBclUri();
System.Uri u = uri as System.Uri; // casts the dynamic to static fine

工作没问题。我现在可以使用强类型 Uri 对象,就像它最初是静态实例化的一样。

然而....

现在我想定义我自己的 C# 类,该类将在动态领域中更新,就像我对 Uri 所做的那样。我的简单 C# 类:

namespace Entity
{
    public class TestPy // stupid simple test class of my own
    {
        public string DoSomething(string something)
        {
            return something;
        }
    }
}

现在在 Python 中,新建一个该类型的对象并返回它:

sys.path.append(r'C:..path here...')
clr.AddReferenceToFile("entity.dll")
import Entity.TestPy

def GetTest():
    return Entity.TestPy(); // the C# class

然后在 C# 中调用 getter:

dynamic test = scriptEngine.GetTest();
Entity.TestPy t = test  as Entity.TestPy; // t==null!!!

在这里,演员阵容不起作用。请注意,“测试”对象(动态)是有效的——我可以调用 DoSomething()——它只是不会转换为已知的静态类型

string s = test.DoSomething("asdf"); // dynamic object works fine

所以我很困惑。 BCL 类型 System.Uri 将从动态类型转换为正确的静态类型,但我自己的类型不会。显然有一些我不明白的事情......

--

更新:我做了很多测试,以确保我的程序集引用全部正确排列。我更改了引用的程序集版本号,然后查看了dynamicC# 中的对象 GetType() 信息——它是正确的版本号,但它仍然不会转换回已知的静态类型。

然后,我在控制台应用程序中创建了另一个类来检查是否会得到相同的结果,结果是积极的:我可以获得dynamic在 C# 中引用在我的 Python 脚本中实例化的静态类型,但它不会正确地转换回已知的静态类型。

--

更多信息:

Anton 在下文中指出,AppDomain 程序集绑定上下文可能是罪魁祸首。经过一些测试后,我认为很有可能是这样。 。 。但我不知道如何解决它!我不知道程序集绑定上下文,因此感谢 Anton,我对程序集解析和其中出现的微妙错误有了更多的了解。

因此,在启动脚本引擎之前,我通过在 C# 中对事件放置一个处理程序来观察程序集解析过程。这让我可以看到 python 引擎启动并且运行时开始解析程序集:

private static Type pType = null; // this will be the python type ref

// prior to script engine starting, start monitoring assembly resolution
AppDomain.CurrentDomain.AssemblyResolve 
            += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

...并且处理程序设置 var pType到 python 正在加载的类型:

static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{

    if (args.LoadedAssembly.FullName == 
        "Entity, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null")
    {
        // when the script engine loads the entity assembly, get a reference
        // to that type so we can use it to cast to later.
        // This Type ref magically carries with it (invisibly as far as I can 
        // tell) the assembly binding context
        pType = args.LoadedAssembly.GetType("Entity.TestPy");
    }
}

因此,虽然 python 使用的类型在 C# 中是相同的,但我认为(如 Anton 所提议的)不同的绑定上下文意味着对于运行时来说,两种类型(“加载绑定上下文”中的一种类型和'loadfrom 绑定上下文)是不同的——所以你不能转换到另一个。

现在我已经掌握了由 Python 加载的类型(及其绑定上下文),你瞧,在 C# 中我可以将动态对象转换为这个静态类型,并且它可以工作:

dynamic test = scriptEngine.GetTest();
var pythonBoundContextObject = 
       Convert.ChangeType(test, pType); // pType = python bound

string wow = pythonBoundContextObject .DoSomething("success");

但是,叹息,这并不能完全解决问题,因为 varpythonBoundContextObject虽然类型正确,仍然带有错误的程序集绑定上下文的污点。这意味着我无法将其传递给代码的其他部分,因为我们仍然有这个奇怪的类型不匹配绑定上下文的无形幽灵让我感到冷漠。

// class that takes type TestPy in the ctor... 
public class Foo
{
    TestPy tp;

    public Foo(TestPy t)
    {
        this.tp = t;
    }
}

// can't pass the pythonBoundContextObject (from above): wrong binding context
Foo f = new Foo(pythonBoundContextObject); // all aboard the fail boat

因此,解决方案必须在 Python 方面:让脚本加载到正确的程序集绑定上下文中。

在Python中,如果我这样做:

# in my python script
AppDomain.CurrentDomain.Load(
    "Entity, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null");

运行时无法解析我的类型:

import Entity.TestPy #fails

以下是 IronPython 团队的回答,涵盖了相同的问题:

与共享 C# 类库的 C# / IronPython 互操作 https://stackoverflow.com/questions/3009213/c-ironpython-interop-with-shared-c-class-library/3011147#3011147

(提升自http://lists.ironpython.com/pipermail/users-ironpython.com/2010-September/013717.html http://lists.ironpython.com/pipermail/users-ironpython.com/2010-September/013717.html )

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 4.0:将动态转换为静态 的相关文章

随机推荐

  • 按多列聚合,对一列求和并保留其他列?根据聚合值创建新列? [复制]

    这个问题在这里已经有答案了 我有一个包含销售的数据框 我需要将 df 聚合 2 列ProductID and Day并对不同列中每个聚合组的值求和Amount现在它显示总数 我希望保留也可以分组的其他列 行之间的值相同 在这种情况下只是Pr
  • Mvvmlight 工具包 WPF4.5 中不存在 EventToCommand

    我正在使用最新的 MVVM Light Toolkit 版本 4 1 26 24928 并且正在使用 WPF 4 5 编写程序 现在我无法在 VS2012 XAML 文件中使用 EventToCommand 它说命名空间 clr names
  • ASP.Net 捆绑导致 HTTPS 错误

    当 web config 中的调试标志设置为 true 时 为什么会出现以下错误 混合内容 页面位于 https example com https example com 已加载完毕 HTTPS 但请求了不安全的脚本 http examp
  • hibernate.default_schema 是什么意思?

    我正在读一本Ben Scheirman 的博客文章 http benscheirman com 2007 12 blame nhibernate why not关于他为了提高性能而进行的一些 NHibernate 调整 文章最后有 第 7
  • Terraform:添加单个规则时,所有安全组规则都会被销毁并替换

    地形信息 地形 v0 12 18 提供商 aws v2 43 0 提供者 模板 v2 1 2 我定义了一个安全组 如果我跑terraform plan or terraform apply与我现有的堆栈相比 没有任何待处理的更改 状态完全是
  • 使用 EF、存储库、实体清理解决方案(项目)结构

    我喜欢保持项目的结构尽可能干净 样本 BlogApp sln BlogApp Data BlogModel edmx the EF mappings Post cs I end up having partial classes in he
  • EL表达式语言中的instanceof检查

    有没有办法执行instanceof入住 EL 吗 E g
  • 如何用刻度线包裹 D3 标签

    我正在尝试让我的标签正确包装 我需要使刻度线和标签相匹配 我正在对标签使用换行功能 但无法使其与 tspan 一起使用 工作演示 https codesandbox io s react d3 pie chart forked nhh85
  • 为什么使用 SimpleDateFormat 时出现 ParseException [重复]

    这个问题在这里已经有答案了 我用eclipse写了下面的代码 String d 2014 6 1 21 05 36 SimpleDateFormat sdf new SimpleDateFormat yyyy MM dd HH mm ss
  • MySQL 中的条件内连接语句

    有没有一种方法可以根据另一个表中字段的值有条件地更改我要内部联接的表 这是我到目前为止得到的 但它是错误的 SELECT j jobID j jobNumber CASE WHEN j idType dealership THEN d de
  • GCD:如何更改计时器触发间隔

    无论如何 这听起来可能是一个新手问题 我对 GCD 很陌生 我有以下代码 int interval 2 int leeway 0 dispatch queue t queue dispatch get global queue DISPAT
  • Scrapy 抓取 div 具有多个类?

    我正在尝试使用 产品 类来获取 div 问题是 一些具有 product 类的 div 也具有 product small 类 所以当我使用xpath div class product 它仅捕获具有一个类的 div 而不捕获多个类的 di
  • 使用 PowerShell 对文件进行 AES 加密

    我能够使用此脚本成功对文件进行 AES 加密here https gallery technet microsoft com EncryptDecrypt files use 65e7ae5d file 165403 14 使用 Windo
  • 通过 Python 更改 Konsole 标题

    如何更改 Python 中的 Konsole 标题 我找到了这段代码 gt gt gt import sys gt gt gt sys stdout write x1b 2 test x07 但它仅适用于 Gnome 终端 不适用于 Kon
  • 如何从 C# 执行批处理文件?

    解决方案见文末 我不认为这会很难 我有一个命令文件 da cmd 其中包含 copy b d 7zS sfx d config txt d files 7z d setup exe 但 C 的这些行不会执行它 Process Start d
  • 更改 pdf 和非 Google 文档(EDU 域)的 acl

    我在尝试从 Google Apps 脚本 Google Apps for Education 更改文件所有权时收到此错误 GDataServiceException您尚无法更改该项目的所有者 我们正在努力 相同的代码适用于 Google A
  • 如何在mysql中存储类型可以是数字、日期或字符串的数据

    我们正在开发一个监控系统 在我们的系统中 值是由运行在不同服务器上的代理报告的 报告的观察结果可以是如下值 一个数值 例如 CPU USAGE 55 表示 55 的 CPU 处于使用状态 使用 某些事件被解雇 例如 备份完成 状态 例如SQ
  • PHP 中 preg_replace() 的字符串的最大长度?

    我发现如果我尝试在很长的字符串上使用 preg replace PHP 会向我的浏览器返回一个空页面 而不显示错误消息 我能够在我的测试环境中重现这个错误 preg replace 可以处理的字符串的最大长度是多少 是否可以增加这个长度 对
  • Firestore 查询 - 一对多关系

    我将开发 Android 移动应用程序并使用 Firebase 作为后端 我是 NoSql Firestore 的新手 在我的应用程序中 用户有很多主题 一个主题有很多帖子 帖子有很多评论和一张图片 用户也有很多追随者 在这种情况下 我如何
  • C# 4.0:将动态转换为静态

    这是一个与我问的另一个问题相关的分支问题here https stackoverflow com questions 2783616 net 4 0 dynamic object used statically 我将其分开 因为这实际上是一