我的C#COM库不能正常工作;无法实例化类和方法显示为属性

时间:2011-08-10 13:51:13

标签: c# vba com

我正在用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中。但是,当我使用X12Segment类型调暗变量时,然后放入点运算符,弹出的IntelliSense窗口向我显示ToString()是属性,而不是方法。此外,ToString的重载显示为ToString_2。当我尝试Set seg = New X12Segment时,VBA告诉我这是对New关键字的无效使用。

我在这里缺少什么?

更新

我根据下面的评论和答案修改了我的代码,我的New解决方案无效,而且我的ToString重载在IntelliSense中显得质朴。然而,出现了一个新问题;尝试访问Fields会给我带来错误。 seg.Fields = someStringArray给我一个错误,说“标记为受限制的函数或接口,或者函数使用Visual Basic中不支持的自动化类型”。

1 个答案:

答案 0 :(得分:2)

[ComVisible]类必须具有无参数构造函数。 COM没有将参数传递给构造函数的机制。您只提供了带参数的构造函数,这就是VBA不允许您使用New关键字的原因。

COM也不支持方法重载。您需要为方法指定不同的名称。如果不这样,那么类型库导出器将自动处理它。因此ToString_2()。