1

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

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

情况:
我有一个处理一大堆数据的解决方案;我使用字符串来包含每条数据的标识符,但刚刚将其换成了一个类(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 的语法,但我不喜欢它不执行以下操作之一的事实:

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 as string,s2 as string),(s1 as string,s2 as string,s3 as string)等)时,我觉得有点蹩脚,还发现你可以'

那么,有谁知道让 String.Concat 表现得像老式串联一样的方法,还是我应该避免 String.Concat 支持老式串联?
(我不打算使用 StringBuilder,因为我只连接几个字符串,我不相信这是一个适合的地方)。

4

2 回答 2

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"

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

于 2013-03-25T12:39:52.360 回答
0

您是否需要覆盖ToString甚至确保为此调用它?FeatureIdentifier公开named的属性或类似的东西似乎更合适Identifier,然后你可以这样做:

Dim myOutputValue as string = String.Concat(x.Identifier, "_ANCHOR.txt")
于 2013-03-25T12:10:48.200 回答