Параметры метода соответствуют сигнатуре, но все еще получают ошибку - PullRequest
0 голосов
/ 22 декабря 2010

Я нахожусь в процессе преобразования библиотеки 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

Тем не менее, в VS10 в файле C # я получаю красное закорочение при этом вызове со следующей ошибкой:

Наилучшее перегруженное совпадение метода для [метода] имеет недопустимые аргументы

Это был рабочий код в VB. Что я делаю не так?

Ответы [ 3 ]

5 голосов
/ 22 декабря 2010

Вам нужно передать второй параметр как ref.
Однако вы не можете передать this как ref (, если это не структура ), поэтому вам понадобится временныйпеременная.

Обратите внимание, что параметр почти наверняка не должен быть ref во-первых.

2 голосов
/ 22 декабря 2010

Согласно документации , ByRef в VB для ссылочных типов не совпадает с ref в C #. Это скорее означает, что функция может изменить переменную.

Итак, просто удалите ref из определения функции:

private static void FillOrder(DataRowView row, Order o)

Кстати, ваш Order a class или struct?

1 голос
/ 22 декабря 2010

Насколько я помню, всегда были проблемы с параметрами ByVal и ByRef / 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 по значению ;это просто означает, что ссылка на экземпляр передается по значению.Функция все еще может изменять элементы этой ссылки.Теперь попробуйте следующее:

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 не влияет на Person с именем me, поскольку параметр передаетсязначение.Однако AssignByReference может изменить значение этого параметра в методе, который его вызвал, поэтому второй вызов Console.WriteLine(me.LastName) отражает обновленную ссылку.

...