我正在尝试基于Scott Hanselman's blog在VB中编写ToCSV()扩展名。可能是我的C#到VB不正确,但一切看起来都是正确的。 我添加了一个模块:
<System.Runtime.CompilerServices.Extension>
Public Function ToCSV(Of T)(items As IEnumerable(Of T)) As String
Try
Dim csvBuilder = New StringBuilder()
Dim properties = GetType(T).GetProperties()
For Each item As T In items
'' Test Code
Dim newline As String = ""
For Each l2 As Reflection.PropertyInfo In properties
' This works
newline &= l2.GetValue(item, Nothing)
' This works too
Dim int As Integer = 1234
Dim s As String = int.ToCSVValue()
'This works
Dim nl = l2.GetValue(item, Nothing)
' This blows up with "Public member 'ToCSVValue' on type 'Integer' not found."
' The Debugger type shows "Object {Integer}" which I assume to mean that the debugger interprets the object as an integer.
nl = nl.ToCSVValue()
Next
' Original code
Dim line As String = String.Join(",", properties.Select(Function(p) p.GetValue(item, Nothing).ToCSVValue()).ToArray())
csvBuilder.AppendLine(line)
Next
Return csvBuilder.ToString()
Catch ex As Exception
Throw
End Try
End Function
<System.Runtime.CompilerServices.Extension>
Private Function ToCSVValue(Of T)(item As T) As String
If item Is Nothing Then
Return """"""
End If
If TypeOf item Is String Then
Return String.Format("""{0}""", item.ToString().Replace("""", "\"""))
End If
Dim dummy As Double
If Double.TryParse(item.ToString(), dummy) Then
Return String.Format("{0}", item)
End If
Return String.Format("""{0}""", item)
End Function
当我用以下内容打电话时:
Dim s As String = ctx.Customers.Where(Function(x) x.CustomerID = 123456).Select(Function(x) New With {.CustomerID = x.CustomerID, .CustomerName = x.CustomerName}).ToCSV()
它到达ToCSV功能就好了。它识别传入的项目。它抽出第一个项目并看到其中有2个字段。一切都好!
GetValue()工作正常。
如果我创建一个静态整数并在其上调用ToCSVValue,它可以正常工作。 如果我创建一个静态字符串并在其上调用ToCSVValue,它可以正常工作。
当我在GetValue()上调用ToCSVValue时,我得到: 公共成员&#39; ToCSVValue&#39;在类型&#39;整数&#39;没找到。
同样,如果我在数据集中只有字符串,我得到: 公共成员&#39; ToCSVValue&#39;在类型&#39;字符串&#39;没找到。
理想情况下,这可以在&#34;原始代码&#34;中使用。部分,我可以杀死所有其他测试代码。
任何人都可以告诉我发生了什么以及为什么&#34;(Of T)&#34;是不是使用get getValue()类型,但是它适用于直接转换类型?
答案 0 :(得分:1)
您需要选择“推断”&#39;。 当我使用Option Infer On时,它可以正常工作。
如果你不使用它,那么VB正在使用&#39;对象&#39;每当你离开这个类型时。
此外,虽然这不会导致您的问题,但ToCSV方法的正确转换是:
Public Function ToCSV(Of T As Class)(items As IEnumerable(Of T)) As String
答案 1 :(得分:0)
简短的回答是,将其称为方法ToCSVValue(p.GetValue(item, Nothing))
将与C#版本一样。
答案越长,您就无法在VB中Object
调用扩展方法。在VB中Object
更像是C#中的dynamic
。例如:
<Extension()> Function toStr(Of T)(item As T) As String
Return item.ToString
End Function
然后这将导致编译时警告&#34; Late bound resolution; runtime errors could occur.
&#34;和运行时错误&#34; Public member 'toStr' on type 'Integer' not found.
&#34;,但它可以在C#中工作:
Dim i As Object = 123
Dim s = i.toStr