Chciałbym przekonwertować tę pojedynczą linię kodu z VB.NET na C #:

Private callback As clsCompareLibs.ResultCallback = AddressOf zipCallback

Jak mogę przekonwertować powyższy kod do C #? Aplikacja działa, jeśli dodam następujące wiersze kodu, ale bez paska postępu, a funkcja Zipcallback jest nazywana, ale nigdy nie wchodzi w inny część:

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

Kodeksu dla 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

W Main:

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

Dysponuj:

Public Delegate Sub ResultCallback(ByRef _zipData As ZipData)
0
Molnar Istvan 14 grudzień 2019, 18:56

1 odpowiedź

Najlepsza odpowiedź

Metoda zipCallback jest członkiem klasy. Ponieważ metoda może korzystać z innych członków tego typu klasy, potrzebujesz również instancji klasy do użycia z delegatem, więc kod zna, do której można spojrzeć, jeśli się odnosi się inny członek.

Aby pomóc zrozumieć, pomyśl o tym kodzie:

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"}

Teraz wyobraź sobie, próbując użyć Foo.Bar() jako delegat Callback. Szukasz różnych wyników w zależności od tego, czy użyjesz instancji x lub instancji y. Który chcemy? A może całkowicie oznaczaliśmy inną instancję. Chodzi o to, że musisz wiedzieć.

Zamiast tego:

AddressOf Bar

Potrzebujesz tego:

AddressOf x.Bar

Lub

AddressOf y.Bar

Oryginalny projekt zarządza to Wystąpiono referencje instancji {x0}} (this w C #). Działa, ponieważ zipCallback() i kod używający go z AddressOf są zarówno w w tej samej klasie , więc mamy dorozumianą instancję.

Nie jest jasne, że pozostaje true z kodem w pytaniu. Jeśli metoda zipCallback() została przeniesiona do innej klasy z klasy Main w projekcie, musisz wiedzieć, która instancja klasy używasz jako część AddressOf} komunikat.

Dla kompletności, druga opcja to kod VB przy użyciu Module zamiast Class. W takim przypadku odpowiednik C # powinien mieć static class, a metoda powinna być również oznaczona static (Shared w VB Parlenance).

0
Joel Coehoorn 14 grudzień 2019, 19:27