VB.Net - “With”和闭包不能混用

2023-11-26

只是想我会分享这个以防其他人遇到这个问题。
我今天做了类似的事情,我花了一段时间才弄清楚为什么这会在运行时导致问题。

这段代码:

Public Class foo
  Public bar As String = "blah"
End Class

Public Sub DoInline()
  Dim o As New foo
  Dim f As Func(Of String)
  With o
    f = Function() .bar
  End With
  Try
    Console.WriteLine(f.DynamicInvoke())
  Catch ex As Reflection.TargetInvocationException
    Console.WriteLine(ex.InnerException.ToString)
  End Try
End Sub

抛出 NullReferenceException。似乎 With 正在使用闭包作为其临时存储,并且在“End With”处,它将闭包的变量设置为 Nothing。

以下是 RedGate Reflector 中的代码:

Public Shared Sub DoInline()
    Dim o As New foo
    Dim $VB$Closure_ClosureVariable_7A_6 As New _Closure$__1
    $VB$Closure_ClosureVariable_7A_6.$VB$Local_VB$t_ref$L0 = o
    Dim f As Func(Of String) = New Func(Of String)(AddressOf $VB$Closure_ClosureVariable_7A_6._Lambda$__1)
    $VB$Closure_ClosureVariable_7A_6.$VB$Local_VB$t_ref$L0 = Nothing 
    Try 
        Console.WriteLine(RuntimeHelpers.GetObjectValue(f.DynamicInvoke(New Object(0  - 1) {})))
    Catch exception1 As TargetInvocationException
        ProjectData.SetProjectError(exception1)
        Console.WriteLine(exception1.InnerException.ToString)
        ProjectData.ClearProjectError
    End Try
End Sub

注意

$VB$Closure_ClosureVariable_7A_6.$VB$Local_VB$t_ref$L0 = Nothing 

我真正能问的唯一“问题”是;这是一个错误还是一个奇怪的设计决策,由于某种原因我没有看到。 从现在开始我几乎会避免使用“With”。


此行为是“设计使然”,是由于经常被误解的细节造成的With陈述。

The With语句实际上将表达式作为参数而不是直接引用(即使它是最常见的用例之一)。语言规范第 10.3 节保证表达式传递到With块仅被评估一次并且可用于执行With陈述。

这是通过使用临时来实现的。所以当执行一个.Membera 内的表达式With声明您访问的不是原始值,而是指向原始值的临时值。它允许其他有趣的场景,如下所示。

Dim o as New Foo
o.bar = "some value"
With o   
  o = Nothing
  Console.WriteLine(.bar) ' Prints "some value"
End With

这是有效的,因为在内部With您没有进行操作的语句o而是临时指向原始表达式。这个临时对象只能保证在该对象的生命周期内一直存在With声明,因此是Nothingd 最后出来。

在您的示例中,闭包正确捕获了临时值。因此,当它在之后执行时With语句完成临时是Nothing并且代码正确地失败了。

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

VB.Net - “With”和闭包不能混用 的相关文章

随机推荐

  • SQLite 与使用数字的表名有关的问题?

    我正在开发一个应用程序 它要求用户选择这样格式的年份1992 1993来自旋转器 表名也被命名为1992 1993这个想法是使用 SQL 通过这样的语句提取该表中的值选择 1992 1993 但是 当我运行模拟器时 它会抛出错误 如果我随后
  • 使用 Zend Framework 和 PHP 发送电子邮件

    我正在制作一个表单 当用户输入他们的电子邮件帐户并单击发送时 一封电子邮件将发送到他们的电子邮件帐户 我已经把一切都解决了 只是它不会将电子邮件发送到我的帐户 有人有主意吗 是否有我遗漏的配置或其他什么 这是我的控制器的示例 public
  • 覆盖 json.Marshal 使用的布局来格式化 time.Time

    在Golang中 有没有办法使通用encoding jsonMarshal 在编组时使用不同的布局time Time fields 基本上我有这个结构 s starttime time Now name ali 我想使用编码为 jsonen
  • 如何从 Windows 窗体连接到 MySQL?

    如何从 Windows 窗体连接到 MySQL 数据库 这里有大量连接字符串示例 http www connectionstrings com
  • GetProperties() 返回接口继承层次结构的所有属性

    假设以下假设的继承层次结构 public interface IA int ID get set public interface IB IA string Name get set 使用反射并进行以下调用 typeof IB GetPro
  • 如何将资源嵌入到 .NET PE 可执行文件中?

    如何在 Visual Studio 2010 的 NET PE 可移植可执行文件 中包含资源 In the 旧时光我们将创建一个资源脚本文件 wumpa rc jqueryjs RCDATA jquery js SplashLogo PNG
  • 主脑极小极大算法

    我正在尝试在 python 中实现 Donald Knuth 的密码破解算法 只需不超过 5 步 我已经多次检查了我的代码 它似乎遵循算法 如下所示 http en wikipedia org wiki Mastermind board g
  • GroupBy pandas DataFrame 并选择最常见的值

    我有一个包含三个字符串列的数据框 我知道第三列中唯一的一个值对于前两个值的每种组合都有效 为了清理数据 我必须按前两列对数据框进行分组 并为每个组合选择第三列的最常见值 My code import pandas as pd from sc
  • 使用 MySQL 将二进制转换为十进制

    我正在尝试在 MySQL 中构建一个查询 该查询连接一堆二进制字段 然后给出 DECIMAL 形式的结果 e g SELECT CONCAT setting1 setting2 setting3 AS settings 可能给了我 101
  • 为什么 onAppear() 当放置在 swiftUI 中的 NavigationView 内的元素上时会执行两次? (Xcode 12.0)

    FirstView Appeared被打印两次 当视图首次加载时一次 当选择 NavigationLink 时再次一次 import SwiftUI struct FirstView View var body some View Navi
  • Javascript .Replace 替代方案

    我正在为 eBay 编写一个模板 但是 eBay 不允许 replace 下面的代码用于翻转选项卡部分 当用户将鼠标悬停在选项卡 a 上时 相应的 div div a 变得可见 有没有一种解决方法可以让代码在不使用 replace 的情况下
  • 这个 O(N*k) 排序算法是什么?

    当工作 BrainF 最快的排序 我发现了这个算法 它是O N k 其中k是输入中的最大值 它需要 O N 额外的存储空间 物理上的类比是你有 N 堆令牌 栈的高度代表要排序的值 每个标记代表一个位 为另外 N 堆留出空间 您从每个有令牌的
  • 使用 R 从 XTS 对象中提取该月第一个工作日的回报

    我对 R 非常陌生 所以如果我在解释这个问题时出现任何术语错误 我深表歉意 我在 csv 文件中有一组每日退货数据 我已设法将其转换为 xts 对象 数据格式为 HighYield EUR MSCI World EUR 2002 01 31
  • 枚举的 XML 序列化

    我在序列化枚举值时遇到问题 这是代码 System Xml Serialization XmlRootAttribute Namespace IsNullable false public class REQUEST System Xml
  • 将图像存储到数据库 blob;从数据库检索到 Picturebox

    您好 我之前发布了此内容并获得了一些帮助 但仍然没有有效的解决方案 感谢上一个问答 我确定我的 保存到数据库 代码以及 检索到图片 代码有问题 即使我手动将图片保存在数据库中 它仍然无法检索 这是我根据网络上的 3 或 4 个示例拼凑而成的
  • 类型错误:需要一个浮点数

    无法发布图片 所以 a i 1 i 1 sin x ln x i 2 i 1 任务 需要找到a1 a2 an n 是自然的并且是给定的 这就是我尝试这样做的方式 import math a k 0 p 0 def factorial n f
  • 使用 JSON.net 序列化 Dictionary

    我正在尝试使用 JSON net 序列化字典 Using JsonConvert SerializeObject theDict 这是我的结果 1 Blah1 false Blah2 false Blah3 None Blah4 false
  • Python 正确使用 __str__ 和 __repr__

    我当前的项目需要大量使用位字段 我找到了一个简单实用的位字段类的配方但它缺少一些我需要的功能 所以我决定扩展它 我刚刚要实施 str and repr 我想确保我遵守惯例 str 应该是非正式和简洁的 所以我让它返回位字段的十进制值 即st
  • 权限被拒绝:用 Java 创建文件

    使用 Mac 在 Eclipse 中编译以下代码后 import java io public class Filer public static void main String args throws IOException File
  • VB.Net - “With”和闭包不能混用

    只是想我会分享这个以防其他人遇到这个问题 我今天做了类似的事情 我花了一段时间才弄清楚为什么这会在运行时导致问题 这段代码 Public Class foo Public bar As String blah End Class Publi