4

在最近的一个问题Import a VB6 structure into C#中,代码包含一个与此类似的固定长度字符串:

Name As String *10

关于如何在 C# 中实现定长字符串的问题中有一些讨论,我提供了一种可能的方法(尽管我建议不要以任何形式使用定长字符串)。但是,其中一个答案提到了 VBFixedStringAttribute,没有进一步解释,我很想知道那是什么。然而,当我去寻找一些关于它的信息时,我在 MSDN 甚至在 Bing 搜索中都找不到。那么问题是“人们如何实际使用它?”

我找不到 C# 代码示例,虽然MSDN 上有一个 VB.NET 的最小示例,但我的 VB.NET 技能不足以弄清楚它发生了什么,所以我可以将它翻译成 C#。

有人可以提供一点代码和解释VBFixedStringAttribute 发生了什么吗?

4

4 回答 4

2

我认为从链接VBFixedStringAttribute Class中需要注意的重要一点是

VBFixedStringAttribute 是信息性的,不能用于将可变长度字符串转换为固定字符串。此属性的目的是修改识别 VBFixedStringAttribute 的方法或 API 调用如何使用结构和非局部变量中的字符串。请记住,此属性不会更改字符串本身的实际长度。

VB.Net 到 C#

Structure Person
    Public ID As Integer 
    Public MonthlySalary As Decimal 
    Public LastReviewDate As Long
    <VBFixedString(15)> Public FirstName As String
    <VBFixedString(15)> Public LastName As String
    <VBFixedString(15)> Public Title As String
    <VBFixedString(150)> Public ReviewComments As String 
End Structure

是相同的

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
struct Person
{
    public int ID;
    public decimal MonthlySalary;
    public long LastReviewDate;
    [VBFixedString(15)]
    public string FirstName;
    [VBFixedString(15)]
    public string LastName;
    [VBFixedString(15)]
    public string Title;
    [VBFixedString(150)]
    public string ReviewComments;
}
于 2012-09-26T17:33:26.763 回答
2

任何属性都需要在其他地方调用 GetCustomAttributes() 来检索它的代码。该代码位于 Microsoft.VisualBasic 命名空间中,即旧版 VB6 I/O 支持方法所在的位置。特别是映射到静态 FileGet 和 FilePut 函数的 FileSystem.FileGetObject() 和 FilePutObject() 方法。直接从 C# 程序中使用这些方法没有问题,只需添加对 Microsoft.VisualBasic 程序集的引用即可。

来自 FileGetObject() MSDN 库文章:

FileGetObject 读取结构的元素,就好像每个都是单独读取一样,除了元素之间没有填充。在磁盘上,用户定义类型的动态数组(用 FilePutObject 编写)以描述符为前缀,该描述符的长度等于 2 加上 8 乘以维数:2 + 8 * NumberOfDimensions。FileOpen 函数中 RecordLength 子句指定的记录长度必须大于或等于读取各个元素(包括任何数组及其描述符)所需的所有字节的总和。VBFixedStringAttribute 类可应用于结构中的字符串字段,以指示写入磁盘时字符串的大小。

于 2012-09-26T17:47:34.100 回答
2

VBFixedStringAttribute没什么特别的。它是这样定义的:

namespace Microsoft.VisualBasic
{
  [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
  public sealed class VBFixedStringAttribute : Attribute
  {
    private int m_Length;

    public int Length
    {
      get
      {
        return this.m_Length;
      }
    }

    public VBFixedStringAttribute(int Length)
    {
       if (Length < 1 || Length > (int) short.MaxValue)
            throw new ArgumentException(Utils.GetResourceString("Invalid_VBFixedString"));
       this.m_Length = Length;
    }
  }
}

使用此属性的主要目的是用于反射目的。如果您正在使用反射并且正在搜索返回字符串的属性,则可以检查此属性以查看其是否为固定字符串,并且可以调用该Length属性以获取大小。即使在 VB.NET 中,该属性实际上也没有任何作用。

于 2012-09-26T18:33:46.270 回答
1

为了使用 VB.NET 的语言特定功能(例如我的命名空间,或者在您的情况下 - VBFixedStringAttribute),您必须添加对 Microsoft.VisualBasic.dll 的引用

之后,您可以简单地将其用作任何其他属性。但请记住,此属性并不会真正影响字符串 - 与大多数属性一样,它只是向将要使用该字符串应具有特定长度的字段的任何人提供信息。所以记住这一点。如果我们已经讨论过字符串长度和验证,建议阅读代码合同:http: //msdn.microsoft.com/en-us/library/dd264808.aspx

于 2012-09-26T17:45:46.577 回答