简体   繁体   English

将 VB.NET 委托转换为 C#

[英]Convert VB.NET delegate to C#

I would like to convert this single line of code from VB.NET to C#:我想将这行代码从 VB.NET 转换为 C#:

Private callback As clsCompareLibs.ResultCallback = AddressOf zipCallback

How can I convert the above code to C#?如何将上述代码转换为 C#? The application works if I add the following lines of code, but without the progressbar and the function zipCallback is called, but never enters the else part:如果我添加以下代码行,应用程序就可以工作,但没有进度条,并且调用了 zipCallback 函数,但从不进入 else 部分:

    public delegate void zipCallbackHendler(ref CompareLibs.ZipData _zipData);
    zipCallbackHendler ziphandler; 
    CompareLibs.ResultCallback callback/*=ziphandler*/;

The code for zipCallback: zipCallback 的代码:

Private Sub zipCallback(ByRef zipData As clsCompareLibs.ZipData)

    Static lastName As String

    If Me.InvokeRequired Then
        Me.Invoke(callback, zipData)
    Else

        With zipData
            If .fileList IsNot Nothing AndAlso .fileList.Count > 0 Then
                ' We've received a list of files. Add them to the listbox.
                Dim names As New List(Of String)
                currentEntries.Clear()

                For Each entry As clsCompareLibs.ShortEntry In .fileList
                    names.Add(entry.name)
                    currentEntries.Add(entry)
                Next

                Me.lbFileList.Items.AddRange(names.ToArray())

                Me.lblFileName.Text = "Complete."

                Try
                    zipLib.Close()
                Catch ex As Exception
                End Try

                me.Cursor = System.Windows.Forms.Cursors.Default
            Else
                ' We're updating the UI with progress data here.

                ' Have we moved on to a new file?
                If lastName <> zipData.currentFileName Then
                    ' If so, set the progress bar to 0.
                    pbCurrentFile.Value = 0 
                    lastName = zipData.currentFileName
                End If

                lblFileName.Text = .operationTitle
                If .currentFileName <> "" Then lblFileName.Text += ": ...\" & Path.GetFileName(.currentFileName)
                If .currentFileBytesCopied > 0 AndAlso .totalBytes > 0 Then
                    pbCurrentFile.Value = CInt((.currentFileBytesCopied / .currentFileLength) * 100)
                    pbTotalBytes.Value = CInt((.totalBytesCopied / .totalBytes) * 100)

                    pbCurrentFile.Refresh()
                    pbTotalBytes.Refresh()
                End If

                If .complete Then
                    zipLib.Close()
                    If .cancel Then 
                        lblFileName.Text = "Canceled."
                        pbCurrentFile.Value     = 0
                        pbTotalBytes.Value      = 0
                    Else
                        endTime = Now
                        If endTime.Subtract(startTime).TotalSeconds > 60 then
                            lblFileName.Text = "Complete. This operation took " & _
                                endTime.Subtract(startTime).Minutes.ToString() & _
                                " minutes, and " & endTime.Subtract(startTime).Seconds.ToString() & " seconds."
                        Else
                            lblFileName.Text = "Complete. This operation took " & _
                                endTime.Subtract(startTime).TotalSeconds.ToString("N1") & _
                                " seconds."
                        End If
                    End If

                    tsbZipFiles.Visible         = True
                    tsbZipFiles.Enabled         = True
                    tsbListZipEntries.Visible   = True
                    tsbCancel.Visible           = False
                    me.Cursor = System.Windows.Forms.Cursors.Default
                End If

                If .errorMessage <> "" Then 
                    MsgBox("" & .errorMessage, MsgBoxStyle.Critical, "Zip Example App")
                    me.Cursor = System.Windows.Forms.Cursors.Default
                End If
            End If
        End With
    End If

End Sub

In main:在主要:

            zipLib = New clsCompareLibs(zipPath, clsCompareLibs.ZipAccessFlags.Create, 1024 * 1024, _
            cbDotNetZip.Checked, CInt(nudCompression.Value), cbZip64.Checked, tbPassword.Text, 100, AddressOf zipCallback)

ResultCallback:结果回调:

Public Delegate Sub ResultCallback(ByRef _zipData As ZipData)

The zipCallback method is a member of a class. zipCallback方法是一个类的成员。 Since the method might use other members of that class type, you also need an instance of the class to use with the delegate, so the code knows what instance to look at if another member is referenced.由于该方法可能使用该类类型的其他成员,因此您还需要该类的一个实例与委托一起使用,因此代码知道如果引用另一个成员时要查看哪个实例。

To help understand, think about this code:为了帮助理解,请考虑以下代码:

Public Class Foo
    Public A As String

    Public Sub Bar(Baz As String)
         A = A & Baz
    End Sub
End Class

Dim x As New Foo With {.A = "x"}
Dim y As New Foo With {.A = "y"}

Now imagine trying to use Foo.Bar() as your delegate callback.现在想象一下尝试使用Foo.Bar()作为您的委托回调。 You'd see different results depending on whether you use the x instance or the y instance.根据您使用的是x实例还是y实例,您会看到不同的结果。 Which one do we want?我们要哪一个? Or maybe we meant a different instance completely.或者也许我们的意思是完全不同的实例。 The point is you need to know.关键是你需要知道。

Instead of this:取而代之的是:

AddressOf Bar

you need this:你需要这个:

AddressOf x.Bar

or或者

AddressOf y.Bar

The original project manages this with an implied Me instance reference ( this in C#). 原始项目使用隐含的Me实例引用(在 C# 中为this )来管理它。 It works because the zipCallback() and the code using it with AddressOf are both in the same class , and so we have an implied instance.它有效是因为zipCallback()和使用它的代码与AddressOf都在同一个 class 中,所以我们有一个隐含的实例。

It's not clear this remains true with the code in the question.目前尚不清楚问题中的代码是否仍然如此。 If the zipCallback() method has moved to a different class from the Main class in the project, you'll need to know which instance of the class you're using as part of the AddressOf statement.如果zipCallback()方法已从项目中的Main类移至不同的类,则您需要知道您正在使用该类的哪个实例作为AddressOf语句的一部分。

For completeness, the other option is VB code using a Module instead of a Class .为了完整起见,另一个选项是使用Module而不是Class VB代码。 In that case, the equivalent C# should have a static class and the method should also be marked static ( Shared in VB parlance).在这种情况下,等效的 C# 应该有一个static class并且该方法也应该标记为static (在 VB 中为Shared )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM