【发布时间】:2011-08-10 13:51:12
【问题描述】:
我正在用 C# 编写一个 COM DLL 来处理 X.12 格式文档的导入和导出,因此我可以在 Access 数据库和自定义程序中使用它来处理我公司的 EDI。我有一个要编译的 DLL,但结果令人失望,我想知道我是否遗漏了什么; COM“从头开始”对我来说是一个新领域(我之前为 Excel 制作了一个功能区,但所有这些都由一个向导处理)。
我已经阅读了this article on MSDN 并遇到了this question here 来让我的 DLL 和 TLB 编译和注册。这是我的 X12Segment 类的骨架和 COM 可见性的接口:
using System;
using System.Collections;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace X12
{
[Guid("28A76274-05EE-45B2-A8EF-ADD5A5B351DE"),
ComVisible(true)]
public interface IX12Segment
{
[DispId(1)]
string SegmentType { get; set; }
[DispId(2)]
string[] Fields { get; set; }
[DispId(3)]
char FieldDelimiter { get; set; }
[DispId(4)]
char SegmentDelimiter { get; set; }
[DispId(5)]
string ToString(char sep, char eol);
[DispId(6)]
string ToString();
[DispId(7)]
Type GetFieldEnum();
}
[Guid("B321599A-E5EC-4510-A021-E9A8B4D6293E"),
ClassInterface(ClassInterfaceType.None),
ComVisible(true)]
public class X12Segment : IX12Segment
{
private string _type;
protected ArrayList _fields;
protected short _minFields = -1;
protected short _maxFields = -1;
protected short[][] _fieldSizes = { new short[] { -1, -1 } };
protected char _sep;
protected char _eol;
public enum Field { }
/// <summary>
/// Creates a new X.12 segment of the supplied type,
/// optionally with a supplied number of fields or
/// values.
/// </summary>
/// <param name="segType">The type of segment (eg "ISA", "GS")</param>
/// <param name="fields">Each string is a field
/// within the segment</param>
public X12Segment(string segType, params string[] fields)
: this(segType)
{
//Do cool stuff
}
/// <summary>
/// Creates a new X.12 segment from a string.
/// </summary>
/// <param name="segType">The type of segment (eg "ISA", "GS")</param>
/// <param name="segment">The string to parse</param>
public X12Segment(string segType, string segment)
: this(segType)
{
//Do cool stuff
}
/// <summary>
/// Creates a new X.12 segment of the supplied type,
/// optionally with a supplied number of fields or
/// values.
/// </summary>
/// <param name="segType">The type of segment (eg "ISA", "GS")</param>
/// <param name="fieldCount">The number of fields
/// in this segment</param>
public X12Segment(string segType, int fieldCount) : this(segType)
{
//Do cool stuff
}
/// <summary>
/// Creates a new X.12 segment of the supplied type,
/// optionally with a supplied number of fields or
/// values.
/// </summary>
/// <param name="segType">The type of segment (eg "ISA", "GS")</param>
public X12Segment(string segType) : this()
{
//Do cool stuff
}
public X12Segment()
{
//Do cool stuff
}
/// <summary>
/// Gets or sets the segment type.
/// </summary>
public string SegmentType
{
get;
set;
}
/// <summary>
/// Gets or sets all of the fields in the segment,
/// in the form of an array of strings.
/// </summary>
public string[] Fields
{
get;
set;
}
/// <summary>
/// Gets or sets the character used to seperate fields in the segment.
/// </summary>
public char FieldDelimiter
{
get;
set;
}
/// <summary>
/// Gets or sets the character denoting the end of the segment.
/// </summary>
public char SegmentDelimiter
{
get;
set;
}
/// <summary>
/// Generates an X.12 formatted segment.
/// </summary>
/// <param name="sep">The field delimiter to use.</param>
/// <param name="eol">The segment delimiter to use.</param>
/// <returns>An X.12 formatted string.</returns>
public string ToString(char sep, char eol)
{
//Do cool stuff
}
/// <summary>
/// Generates an X.12 formatted segment.
/// </summary>
/// <returns>An X.12 formatted string.</returns>
public override string ToString()
{
//Do cool stuff
}
/// <summary>
/// Returns the Type associated with the Field enumeration of this object.
/// </summary>
/// <returns>A System.Type of this object's Field enumeration.</returns>
public virtual Type GetFieldEnum()
{
//Do cool stuff
}
}
}
现在,当我打开 VBA 并添加引用时,该类会显示在 IntelliSense 中。但是,当我 Dim 使用 X12Segment 类型的变量,然后放入点运算符时,弹出的 IntelliSense 窗口显示 ToString() 是一个属性,而不是一个方法。此外,ToString 的重载显示为 ToString_2。当我尝试Set seg = New X12Segment 时,VBA 告诉我这是对 New 关键字的无效使用。
我在这里错过了什么?
更新
我已根据下面的 cmets 和答案修改了我的代码,并且我有解决 New 不工作和我的 ToString 重载在 IntelliSense 中看起来很时髦的解决方案。但是,出现了一个新问题;尝试访问字段给我错误。 seg.Fields = someStringArray 收到一条错误消息,提示“函数或接口标记为受限,或者函数使用 Visual Basic 不支持的自动化类型”。
【问题讨论】:
-
我不明白你的问题。这些 ARE 属性,即使在您的 C# 代码中也是如此。
-
哇。出于某种原因,我认为我拥有的不止这些。但无论哪种方式,ToString 都是一种方法,它显示为一个属性。而且我无法在 VBA 中实例化我的 X12Segment。
-
方法重载在 COM 中无效(以及其他一些技术 - 请参阅 WCF、Web 服务)。这就是为什么您的 ToString() / ToString_2() 会这样显示的原因 - 编译器保护您免受该实现细节的影响...