将字符串解析为多个可变长度字符串(C#)
我目前正在尝试将 VB6 程序转换为 C# 程序。字符串分割结构被广泛使用。例如,
Dim Sample AS String
Sample = "John Doe New York Test Comment"
Public Type Struct1
Name As String * 15
Address As String * 10
Comment As String * 20
End Type
Dim dataStruct As Struct1
Set dataStruct = Sample
当设置dataStruct时,它会自动将值拆分为3个结构成员。 C# 中有没有特殊的函数可以做到这一点。我知道如何做到这一点的唯一方法是通过属性/注释描述字符串的长度和起始位置。还有其他建议吗?
I am currently trying to convert a VB6 program into C#. There was extensive use of string splitting into structure. For example,
Dim Sample AS String
Sample = "John Doe New York Test Comment"
Public Type Struct1
Name As String * 15
Address As String * 10
Comment As String * 20
End Type
Dim dataStruct As Struct1
Set dataStruct = Sample
When the dataStruct is set, it will automatically split value into the 3 structure member. Is there a special function to do this in C#. The only way I know how to do this is thru Attributes/Annotation describing the length and start position of string. Any other suggestion?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以查看 FileHelpers 库,其中包含 执行此操作的方法。
You may take a look at the FileHelpers library which has methods for doing this.
您可以尝试使用隐式运算符:
对于字符串值的解析,您可以使用正则表达式。
You could try using the implicit operator:
For the parsing of the string value you could use a regular expression.
我不知道有什么内置方法可以做到这一点,但对我来说使用属性听起来是一个很好的方法。然后您可以编写代码通过反射设置相关属性。除非字符串中有间隙,否则我会将其表示为相对顺序和长度而不是起始位置 - 然后您可以找到所有属性,按它们的顺序排序(不应该要求是连续的 - 顺序0, 10, 20, 30, 40 使得在必要时添加额外的属性变得更容易)并以这种方式计算出分割。
I don't know of any built-in way to do this, but using an attribute sounds like a good way of doing it to me. You can then write a code to set the relevant properties via reflection. Unless you have gaps in the string, I would express it as relative ordering and length rather than the start position though - then you can just find all the attributes, sort by their ordering (which shouldn't be required to be consecutive - an ordering of 0, 10, 20, 30, 40 makes it easier to add in an extra property if necessary) and work out the split that way.
您可以使用运算符重载来模拟赋值行为。这样,目标类还定义了部件的大小,因此每个类都必须知道输入应该是什么样子。它的代码比 VB 示例多一点。
示例(语法可能不正确,我很少使用运算符重载):
更具可读性的替代方案是隐式创建者模式:
You could use operator overloading to emulate the assignment behaviour. This way the target class also defines the size of the parts so each class has to know how the input should look. It's a little more code than the VB example.
Example (Syntax might not be correct, i use operator overloading very rarely):
A more readable alternative would be an implicit creator pattern:
如果没有 P/Invoke 编组器,这样的结构映射技巧就无法工作。结构的内部组织是不可发现的。 JIT 编译器很容易利用这一点,如果这为结构产生了较小的内存大小,它就会交换成员。只有 [StructLayout] 可以确定它。
Microsoft.VisualBasic 命名空间中还有一个好东西可以让这一切变得容易。 TextFieldParser 类可以通过一次调用轻松转换这样的字符串。例如:
请注意,您发布的原始字符串与结构声明不匹配,我必须修改字段宽度。另请注意,TextFieldParser 接受任何流,它不必是存储在 StringReader 中的字符串。读取文件的 StreamReader 是更典型的用途。
Structure mapping tricks like this cannot work without the P/Invoke marshaller. The internal organization of a structure is not discoverable. The JIT compiler readily takes advantage of this, it swaps members if that produces a smaller memory size for the structure. Only a [StructLayout] can nail it down.
There's another goody in the Microsoft.VisualBasic namespace that makes this easy to do. The TextFieldParser class can readily convert strings like this with a single call. For example:
Note that the original string you posted didn't match the structure declaration, I had to modify the field widths. Also note that TextFieldParser takes any stream, it doesn't have to be a string stored in a StringReader. A StreamReader that reads a file would be the more typical use.