【问题标题】:C# underscore as argument to VB.NETC# 下划线作为 VB.NET 的参数
【发布时间】:2019-03-26 20:10:21
【问题描述】:

我有以下要转换为 VB.NET 的 C# 代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System;
using OpenCvSharp;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string sPath = "c:\\users\\myuser\\desktop\\lenna.png";

            using (var src = new Mat(sPath, ImreadModes.Color))
            using (var srcGray = new Mat(sPath, ImreadModes.GrayScale))
            using (var hsv = new Mat())
            using (var dst = new Mat())
            {
                Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV);
                Cv2.CvtColor(srcGray, dst, ColorConversionCodes.GRAY2BGR);

                var hsvChannels = Cv2.Split(hsv);
                var v = hsvChannels[2];

                for (int i = 0; i < 8; i++)
                {
                    using (var bin = new Mat())
                    {
                        Cv2.Threshold(v, bin, i * 32, 255, ThresholdTypes.Tozero);
                        Cv2.Threshold(bin, bin, (i + 1) * 32, 255, ThresholdTypes.BinaryInv);

                        Cv2.FindContours(bin, out var contours, out _, RetrievalModes.External,
                            ContourApproximationModes.ApproxNone);
                        Cv2.DrawContours(dst, contours, -1, Scalar.Red, 1);
                    }
                }

                Window.ShowImages(dst);

                foreach (var m in hsvChannels)
                    m.Dispose();
            }
        }
    }
}

我设法转换了它,但是“_”让我很头疼。

如果我用“Nothing”替换它,编译器会告诉我“不是最具体的”。

如果我这样声明“轮廓”(更具体一点),编译器会告诉我“Nothing”是一个无效参数:

Dim contours As OpenCvSharp.Mat()

这是我的 VB.NET 尝试:

Imports OpenCvSharp

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

        Dim sPath As String = "c:\users\myuser\desktop\lenna.png"

        Using src = New Mat(sPath, ImreadModes.Color)
            Using srcGray = New Mat(sPath, ImreadModes.GrayScale)
                Using hsv = New OpenCvSharp.Mat()
                    Using dst = New Mat()
                        Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV)
                        Cv2.CvtColor(srcGray, dst, ColorConversionCodes.GRAY2BGR)

                        Dim hsvChannels = Cv2.Split(hsv)
                        Dim v = hsvChannels(2)

                        For i As Integer = 0 To 7
                            Using bin = New Mat()
                                Cv2.Threshold(v, bin, i * 32, 255, ThresholdTypes.Tozero)
                                Cv2.Threshold(bin, bin, (i + 1) * 32, 255, ThresholdTypes.BinaryInv)

                                Dim contours
                                Cv2.FindContours(bin, contours, Nothing, RetrievalModes.External, ContourApproximationModes.ApproxNone) // Compiler error occurs here
                                Cv2.DrawContours(dst, contours, -1, Scalar.Red, 1)
                            End Using
                        Next i

                        Window.ShowImages(dst)

                        For Each m In hsvChannels
                            m.Dispose()
                        Next m
                    End Using
                End Using
            End Using
        End Using
    End Sub
End Class

我不确定编译器想从我这里得到什么。有人知道吗? 使用下划线或双下划线(正如一些在线转换器所建议的那样)将不起作用。

这些是 FindContours 的声明:

Public Shared Sub FindContours(image As InputOutputArray, ByRef contours() As Mat, hierarchy As OutputArray, mode As RetrievalModes, method As ContourApproximationModes, Optional offset As Point? = Nothing)

Public Shared Sub FindContours(image As InputOutputArray, ByRef contours As Point()(), ByRef hierarchy() As HierarchyIndex, mode As RetrievalModes, method As ContourApproximationModes, Optional offset As Point? = Nothing)

【问题讨论】:

    标签: c# vb.net arguments


    【解决方案1】:

    C# 中的下划线参数是discard。据我所知,VB 没有类似的东西。由于这是一个out 参数,您需要声明一个本地虚拟变量并传递它:

    Dim contours As Point()()
    Dim unused As HierarchyIndex()
    Cv2.FindContours(bin, contours, unused, RetrievalModes.External, ContourApproximationModes.ApproxNone) 
    

    还请注意,您的 contours 本地声明缺少类型,因此不完整。编译器应将其视为无效而拒绝(如果您使用 Option Strict 进行编译,您应该这样做)。

    【讨论】:

    • 我现在已经按照你的建议做了,并且另外声明了“Dim contours() As OpenCvSharp.Mat”,但是,编译器告诉我“NullException:Parametername 层次结构可能不是 NULL”。
    • @tmighty 谢谢,我用错误的类型声明它。我修好了,现在应该可以了。
    • 编译器告诉我这些参数没有重载。
    • @tmighty 呃,再试一次。我又搞砸了。也就是说,您发布的声明有点奇怪,因为该参数未声明为 ByRef(C# 中为 out),所以这不应该工作 - 或者至少它不等同于 C# 代码。
    • 现在它告诉我“重载错误,因为 New 不可用”。我也试过“Dim used = New OpenCvSharp.OutputArray()”,但结果相同。
    【解决方案2】:

    编译器不知道你想使用什么重载,因为你没有给contours一个类型。指定 contours 是什么类型,Dim contours as Point()Dim contours as Mat

    当您对参数值不感兴趣时​​,在 csharp 中使用下划线 _。因为VB没有out机制,所以必须为下划线参数Dim hierarchy() As HierarchyIndexDim hierarchy As OutputArray指定一个临时变量。

    使用 VB.net 时,请确保指定参数类型 - 并尽可能启用严格的类型检查。这迫使您编写更干净的代码,类型更安全。这将为您省去很多麻烦。

    【讨论】: