Paramarrays 的通用 Concat 扩展方法不适用于 IEnumerable(of String)
受到 Max()/Min() 中的 Javascript 变量参数和函数语言中的列表理解的启发,我尝试使用给定 IEnumerable(of T) 作为结果类型的通用扩展方法在 VB.NET 中获得相同的结果。除了字符串之外,这种方法效果很好。为什么? 这些类型的扩展方法可能被认为是一个坏主意。任何强有力的理由说明为什么这是一个坏主意。
Option Explicit On
Option Strict On
Imports System.Runtime.CompilerServices
Module Module1
Sub Main()
Dim xs As IEnumerable(Of Integer) = 1.Concat(2, 3, 4)
Dim ys As IEnumerable(Of Double) = 1.0.Concat(2.0, 3.0, 4.0)
Dim zs As IEnumerable(Of String) = Concat("1", "2", "3", "4") 'silly but works, I would use a stringbuilder
'Dim zs2 As IEnumerable(Of String) = "1".Concat("2", "3", "4") ' does not work why?
'Gives:
'String' cannot be converted to 'System.Collections.Generic.IEnumerable(Of String)'
'because() 'Char' is not derived from 'String', as required for the 'Out' generic parameter 'T' in 'Interface IEnumerable(Of Out T)'.
'C:\Users\kruse\Documents\Visual Studio 10\Projects\VarArgsExperiment\VarArgsExperiment\Module1.vb 12 45 VarArgsExperiment
Console.ReadLine()
End Sub
<Extension()> _
Function Concat(Of T)(ByVal xs As IEnumerable(Of T), ByVal ParamArray params As T()) As IEnumerable(Of T)
Dim ys As IEnumerable(Of T) = params.AsEnumerable()
Return xs.Concat(ys)
End Function
<Extension()> _
Function Concat(Of T)(ByVal x As T, ByVal ParamArray params As T()) As IEnumerable(Of T)
Dim xs As New List(Of T)
xs.Add(x)
Dim ys As IEnumerable(Of T) = params.AsEnumerable
Return xs.Concat(ys)
End Function
End Module
...为了简短起见,剪掉了模块的其余部分。 Als 为 Action 对象编写了一些 Add、Cast 和 Apply 方法。
Inspired by Javascripts variable Arguments in Max()/Min() and list comprehension in functional languages I tried to get the same in VB.NET using Generic Extension methods given IEnumerable(of T) as resulttype. This works well excepts for strings. Why?
These kind of extension methods may be considered a bad idea. Any strong reason Why this is a bad idea.
Option Explicit On
Option Strict On
Imports System.Runtime.CompilerServices
Module Module1
Sub Main()
Dim xs As IEnumerable(Of Integer) = 1.Concat(2, 3, 4)
Dim ys As IEnumerable(Of Double) = 1.0.Concat(2.0, 3.0, 4.0)
Dim zs As IEnumerable(Of String) = Concat("1", "2", "3", "4") 'silly but works, I would use a stringbuilder
'Dim zs2 As IEnumerable(Of String) = "1".Concat("2", "3", "4") ' does not work why?
'Gives:
'String' cannot be converted to 'System.Collections.Generic.IEnumerable(Of String)'
'because() 'Char' is not derived from 'String', as required for the 'Out' generic parameter 'T' in 'Interface IEnumerable(Of Out T)'.
'C:\Users\kruse\Documents\Visual Studio 10\Projects\VarArgsExperiment\VarArgsExperiment\Module1.vb 12 45 VarArgsExperiment
Console.ReadLine()
End Sub
<Extension()> _
Function Concat(Of T)(ByVal xs As IEnumerable(Of T), ByVal ParamArray params As T()) As IEnumerable(Of T)
Dim ys As IEnumerable(Of T) = params.AsEnumerable()
Return xs.Concat(ys)
End Function
<Extension()> _
Function Concat(Of T)(ByVal x As T, ByVal ParamArray params As T()) As IEnumerable(Of T)
Dim xs As New List(Of T)
xs.Add(x)
Dim ys As IEnumerable(Of T) = params.AsEnumerable
Return xs.Concat(ys)
End Function
End Module
... Cut of the rest of the module for being brief. Als wrote some methods for Add, Cast and an Apply for Action objects.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
字符串是
IEnumerable
,字符串和 char 之间没有关系。您可以将其视为维度问题,字符串通常可以视为字符数组。 char[] 不等于 char,也永远不会。 System.String 还实现了一个 Concat 方法,它可能会扰乱您的类型签名,因此您可能需要小心。A string is an
IEnumerable<char>
, and there's no relation between a string and char. You can think of it as a problem with dimensions, a string can usually be thought of as an array of char. char[] does not equals char, nor will it ever. System.String also implements a method Concat which can mess with your type signature so you might wanna be careful with that.