具有非字符串参数的String.Concat,意外行为

时间:2013-03-25 12:07:31

标签: vb.net string .net-4.0 refactoring concat

总结:我正在尝试让String.Concat在将字符串粘在一起时使用引用类型的ToString重载。

编辑:添加了这个概述:下面的示例代码是我的实际代码的精简提取 - 因此,当重构时,如果我只有两行代码,它将立即显而易见。这里的重要问题(对我来说)是我从一个字符串变为一个对象,并且没有来自String.Concat的编译错误。同样,它的行为不是我所期望的(使用我的对象的字符串方法,而不是沼泽标准对象名称)。如果我一直在使用“&”,那就会出现编译错误。我担心String.Concat语法糖可能会导致本来可以避免的错误(在这种情况下重构时)。我想知道是否有一种方法可以改变String.Concat的行为,或者我是否应该认为它是危险的。

情况:
我有一个处理整堆数据的解决方案;我正在使用一个String来包含每个数据的标识符,但是刚刚将它换成了一个类(FeatureIdentifier),使我能够扩展标识符以包括诸如批次之类的东西。

我重构了我的代码,以便我使用这个类而不仅仅是字符串。当重构这种类型的东西(正确或错误)时,我倾向于将编译错误作为待办事项列表。

现在,我是一个自学成才的程序员,我可能有点习惯(如果他们让我做任何新的事情而不是让他做我已经做过的事情,我倾向于看新功能)只会更容易)我只是遇到让我难过的事情。

所以,我将我的标识符粘贴到类型的下划线上。我的代码看起来像这样:
Dim x as string = "MyIdentifer"
dim myOutputValue as string = String.Concat(x,"_ANCHOR.txt")
运行这个我得到myOutputValue等于“MyIdentifier_ANCHOR.txt”。重构后,我的代码看起来像这样:
Dim x as new FeatureIdentifier("MyIdentifier")
dim myOutputValue as string = String.Concat(x,"_ANCHOR.txt")
运行它我的myOutputValue等于“MyNamespace.FeatureIdentifier_ANCHOR.txt”。

踢了我自己并在我的类上实现了ToString方法,我再次运行它并获得完全相同的输出(即“MyNamespace.FeatureIdentifier_ANCHOR.txt”)。如果我这样做:?x.ToString,我得到“MyIdentifier”,所以我确定我已经正确实现了ToString。

所以,这是我的问题。我喜欢String.Concat的语法,但我不喜欢它不执行以下操作的事实:
a)在它引用的引用类型上调用ToString或者b)如果你传递非基于字符串的参数,则抛出编译错误。旧学校:x& “_ANCHOR.txt”给了我一个编译错误(我在重构时会提到它)。

这是我尝试过的:
我试过用扩展名来掩盖String.Concat函数(类似这样:
<System.Runtime.CompilerServices.Extension()> Public Function Concat(...some arguments...) As String
Return String.Concat(...some arguments...)
End Function
)但遇到两个问题:
1)当试图将参数的类型缩小到字符串以导致编译错误时,我意识到参数是一个参数数组,因此首先是对象。所以在那里失败。
2)当我尝试进行多次重载时((s1为字符串,s2为字符串),(s1为字符串,s2为字符串,s3为字符串)等),我觉得有点蹩脚,也发现你可以'实际上重载静态类的扩展(这就是我猜的字符串)。

那么,有没有人知道如何使String.Concat表现得像老式连接一样,或者我应该避免使用String.Concat来支持老派连接吗? (我不打算使用StringBuilder,因为我只连接几个字符串,我不相信这是一个地方)。

2 个答案:

答案 0 :(得分:1)

我不相信你有任何方法可以“修复”String.Concat方法只允许字符串。将其归结为为什么应该尽可能少地创建和使用共享方法的另一个原因。但是,通过运算符重载的奇迹,您可以使自定义类像字符串一样工作。要修复Concat方法,您需要重载CType运算符。要修复字符串连接运算符(&),您需要单独重载该运算符,如下所示:

Public Class FeatureIdentifier
    Public Sub New(id As String)
        Me.Id = id
    End Sub

    Public Property Id As String
    Public Property SomethingElse As Integer

    Public Overloads Shared Widening Operator CType(value As FeatureIdentifier) As String
        Return value.Id
    End Operator

    Public Overloads Shared Operator &(value1 As FeatureIdentifier, value2 As String) As String
        Return value1.Id & value2
    End Operator

    Public Overloads Shared Operator &(value1 As String, value2 As FeatureIdentifier) As String
        Return value1 & value2.Id
    End Operator
End Class

现在您可以像这样使用它:

Dim x As New FeatureIdentifier("MyIdentifier")
Dim myOutputValue As String = String.Concat(x, "_ANCHOR.TXT")

或者像这样:

Dim x As New FeatureIdentifier("MyIdentifier")
Dim myOutputValue As String = x & "_ANCHOR.TXT"

在这种情况下,它就像是一个字符串一样工作。您也可能想要重载其他一些运算符,以防万一。例如,+运算符在应用于两个字符串时也会连接。但是,我应该提醒您,操作员重载可能会导致对不熟悉代码的人造成混淆,因为它会意外地工作,所以只有在真正有意义的情况下才应该使用它。

答案 1 :(得分:0)

您是否需要覆盖ToString,甚至确保要求它?公开名为FeatureIdentifier Identifier的{​​{1}}属性或某些此类事物似乎更合适,然后您可以这样做:

Dim myOutputValue as string = String.Concat(x.Identifier, "_ANCHOR.txt")