我正在将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中的工作代码。我做错了什么?
答案 0 :(得分:5)
您需要将第二个参数传递为ref
但是,您无法将this
作为ref
(unless it's a struct)传递,因此您需要一个临时变量。
请注意,参数几乎绝对不应该是ref
。
答案 1 :(得分:2)
根据documentation,VB中的ByRef
引用类型与C#中的ref
不同。这意味着该函数可能会改变变量。
所以,只需从函数定义中删除ref
:
private static void FillOrder(DataRowView row, Order o)
BTW,是您的Order
class
还是struct
?
答案 2 :(得分:1)
只要我记得,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
的{{1}}实例按价值传递到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
的{{1}}没有影响,因为参数是按值传递的。但是,Person
可以在调用它的方法中更改该参数的值,因此对me
的第二次调用反映了更新的引用。