在几个 showstoppers延迟迁移到.NET 4.6运行时之后,我终于习惯于转移到C#6/VB14编译器,直到遇到VB.NET中的迭代器函数抛弃局部变量的关键问题.
在Visual Studio 2015/msbuild中以发布模式(优化)编译时,以下代码示例将在注释行上抛出空引用异常.
Module Module1
Sub Main()
For Each o As Integer In GetAllStuff()
Console.WriteLine(o.ToString())
Next
Console.ReadKey()
End Sub
Private Iterator Function GetAllStuff() As IEnumerable(Of Integer)
Dim map As Dictionary(Of String, String) = New Dictionary(Of String, String)
Dim tasks As New List(Of Integer)
tasks.Add(1)
For Each task As Integer In tasks
Yield task
Next
'The value of map becomes null here under the new VB14 compiler in Release on .NET 4.6'
For Each s As …Run Code Online (Sandbox Code Playgroud) 使用WinForms,有没有办法提醒控制器改变屏幕位置?
假设您有一个带有按钮的表单,并且您想知道该按钮何时从屏幕上的当前像素位置移动.如果按钮移动到其父窗体上的其他位置,您显然可以使用LocationChanged事件,但如果用户移动了窗体,您如何知道按钮已在视觉上移动?
在这个简化的情况下,快速回答是监视Form的LocationChanged和SizeChanged事件,但是可以有任意数量的嵌套级别,因此监视链上的每个父级对主要表单的那些事件是不可行的.使用计时器来检查位置是否变化也似乎是作弊(以一种糟糕的方式).
简短版本: 只给出一个任意的Control对象,有没有办法知道Control的位置何时在屏幕上发生变化,而不知道控件的父层次结构?
按要求说明:

请注意,此"固定"概念是现有功能,但它目前需要了解父表单以及子控件的行为方式; 这不是我想解决的问题.我想将这个控件跟踪逻辑封装在一个抽象的表单中,"可以"表单可以继承.是否有一些消息泵魔术我可以利用来了解控件何时在屏幕上移动而无需处理所有复杂的父跟踪?
我正在比较sprintf用法的性能,而且我看到的东西有点困扰.我测试了以下4种方法,将ClassWithToString的实例传递给每个(除了PrintInt,它接收到实际的整数值).
type ClassWithToString() =
member this.X = 42
override this.ToString() = this.X.ToString()
let Print item : string =
sprintf "%A" item
let PrintInt item: string =
sprintf "%i" item
let PrintObj item: string =
sprintf "%O" item
let Format item : string =
System.String.Format("{0}", item)
Run Code Online (Sandbox Code Playgroud)
50,000次迭代的结果:
Print (%A): 3143ms
PrintInt (%i): 355ms
PrintObj (%O): 384ms
Format: 8ms
Run Code Online (Sandbox Code Playgroud)
对于"打印",我理解%A正在使用反射,因此那里的迟缓并不令人震惊,尽管对于50k次迭代我总是惊讶于总时间.在此之后,"PrintInt"和"PrintObj"不使用反射,因此速度快一个数量级,这也是有意义的.
令我感到困惑的部分是,鉴于String.Format()sprintf 的结果通常看起来非常慢(并且已经在实时应用程序的配置文件中见证过).为什么sprintf幅度比String.Format()慢?我错过了F#空间有更好的选择吗?