【问题标题】:Method params match signature, but still getting error方法参数匹配签名,但仍然出现错误
【发布时间】:2010-12-22 20:38:50
【问题描述】:

我正在将 VB 库转换为 C#。我的一种方法在 VB 中具有以下签名:

Private Shared Sub FillOrder(ByVal row As DataRowView, ByRef o As Order)

在 C# 中我将其转换为:

private static void FillOrder(DataRowView row, ref Order o)

从我的 Order 类中的构造函数,我正在调用 FillOrder() 方法,如下所示:

DataView dv = //[get the data]
if (dv.Count > 0)
{
    FillOrder(dv[0], this);
}

在 VB 中,这是可行的:

Dim dv As DataView = '[get data]'
If dv.Count > 0 Then
    FillOrder(dv.Item(0), Me)
End If

但是,在 C# 文件的 VS10 中,我在此调用下得到一个红色曲线,并出现以下错误:

[该方法]的最佳重载方法匹配有一些无效参数

这是 VB 中的工作代码。我做错了什么?

【问题讨论】:

  • 我想知道它是如何工作的:this 应该是只读的,对吧?所以你不应该拥有ref this
  • 在 C# 中,您不需要为 Order 参数添加 ref 关键字。它是一个引用类型,你可能不需要通过 ref 传递它。
  • @Oded:什么? refByRef 没有区别。
  • 除非你能给出很好的解释,否则你一开始就不应该使用ref参数。
  • @slaks 使用ref 参数有什么问题?

标签: c# asp.net parameter-passing method-signature


【解决方案1】:

您需要将第二个参数作为ref 传递。
但是,您不能将this 作为ref (unless it's a struct) 传递,因此您需要一个临时变量。

请注意,参数几乎绝对不应该是ref

【讨论】:

  • 但是翻译中的ref真的需要吗?
  • @Vlad:不适用于结构。 @Oded:对于参数,是的。对于论点,没有。
  • 感谢您的帮助。我需要 ref 参数,但我重载了方法以按照我的方式使用它,而另一个没有 ref
  • @Jason:为什么你认为你需要ref参数吗?
【解决方案2】:

根据documentation,VB中ByRef的引用类型与C#中的ref不一样。而是意味着该函数可能会更改变量。

所以,只需从函数定义中删除 ref

private static void FillOrder(DataRowView row, Order o)

顺便说一句,您的Orderclass 还是struct

【讨论】:

  • Order 是一个类。我需要ref 调用,所以我重载了FillOrder() 并让一切正常工作。感谢您的帮助!
  • 错误ByRefref 是一样的。
  • @Jason:你为什么需要ref?您是否在函数内部替换了o
  • @SLaks:证明? (如果它们真的相同,则无法将this 传递为ByRef。)
  • @Vlad:VB 在必要时降级为按值传递。 blogs.msdn.com/b/vbteam/archive/2010/01/26/…
【解决方案3】:

从我记事起,关于ByValByRef/ref 参数一直存在混淆。这是我可以解释的最佳方式:

您只需要通过引用传递一个对象当且仅当您打算用一个不同的引用替换该引用。如果要改变被传递对象的内容,只需要按值传递即可。示例:

Public Class Person
    Public Property FirstName As String
    Public Property LastName As String
End Class

Public Shared Sub ModifyPerson(ByVal someone As Person)
    ' Passed by value          ^^^^^

    someone.LastName = "Doe"
End Sub

Public Shared Sub Main(ByVal args() As String)
    Dim me As New Person
    me.FirstName = "Adam"
    me.LastName = "Maras"

    ModifyPerson(me)

    Console.WriteLine(me.LastName) ' Writes "Doe"
End Sub

是的,Person 的实例名为me 被传入ModifyPerson 按值;这只是意味着对实例的 reference 是按值传递的。函数仍然可以修改该引用的成员。现在,试试这个:

Public Shared Sub Main(ByVal args() As String)
    Dim me As New Person
    me.FirstName = "Adam"
    me.LastName = "Maras"

    AssignByValue(me)
    Console.WriteLine(me.LastName) ' Writes "Maras"

    AssignByReference(me)
    Console.WriteLine(me.LastName) ' Writes "Doe"
End Sub

Public Shared Sub AssignByValue(ByVal someone As Person)
    Dim new As New Person
    new.FirstName = "John"
    new.LastName = "Doe"

    someone = new
End Sub

Public Shared Sub AssignByReference(ByRef someone As Person)
    Dim new As New Person
    new.FirstName = "John"
    new.LastName = "Doe"

    someone = new
End Sub

这些函数不同,因为它们试图修改传入的实际引用。AssignByValue 对名为mePerson 没有影响,因为参数是按值传递的。但是,AssignByReference 可以在调用它的方法中更改该参数的值,因此对 Console.WriteLine(me.LastName) 的第二次调用反映了更新的引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 2019-07-09
    • 2019-06-01
    • 1970-01-01
    相关资源
    最近更新 更多