从C#到VB6生成COM可见列表

3

我有一个ClassLibrary(在Visual Studio 2010 C#中),其中有一个名为Car的类:

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{
    public Car()
    {
        Name = "";
        Parts = new List<string>();
    }

    public string Name { get; set; }

    public List<string> Parts { get; set; }
}

但是,当我在vb6项目中使用它时:没有属性“Parts”:

http://i.imgur.com/x4h3BMp.jpg?1

我该怎么做才能使属性List<>可见?

当然,“AssemblyInfo.cs”文件包含以下内容:

[assembly: ComVisible(true)]

附注:我真的不想为每个列表创建一个类,像这样:

public class Parts
{
    private List<string> _parts;

    public Parts()
    {
        _parts = new List<string>();
    }

    public void Add(string part)
    {
        _parts.Add(part);
    }

    public string GetAt(int index)
    {
        if (0 <= index && index < _parts.Count)
            return _parts[index];
        return "";
    }

    public void Clear()
    {
        _parts.Clear();
    }

    public int Count{ get{ return _parts.Count; } }
}

由于数量太多。
2个回答

3

COM不支持通用集合;您需要使用数组或ArrayList代替:

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{
    public Car()
    {
        Name = "";
        Parts = new string[];
    }

    public string Name { get; set; }

    public string[] Parts { get; set; }
}

如果你想在后台使用List,可以使用List<string>作为支撑变量,然后更改属性访问器以将列表翻译为/从数组翻译:

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{

    private List<string> _Parts;

    public Car()
    {
        Name = "";
        _Parts = new List<string>();
    }

    public string Name { get; set; }

    public string[] Parts 
    { 
        get
        {
            return _Parts.ToArray();
        } 
        set
        {
            _Parts = new List<string>(value);
        } 
    }
}

如果您只是从泛型继承以创建具体定义(例如 class Parts : List<Part>),并添加属性,那么这样做是否可以用于Com Visibility呢? - Jon Egerton
我添加了一个类:[ClassInterface(ClassInterfaceType.AutoDual)] [ProgId("Modem_TAO_Well3DView.Parts")] public class Parts : List { public Parts() { MaxCount = 50; } public static int MAX_COUNT = 50; public int GetMaxCount() { return 50; } public int MaxCount { get; set; } }但是什么都没有显示出来(属性、字段等)。也许你的意思是IList<Part>。 - zhigarartem
我希望有一个类属性,允许访问属性列表。 - zhigarartem

1

我本不想这样做,但是必须这样:

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{
    public Car()
    {
        Name = "";
        Parts = new Parts();
    }

    public string Name { get; set; }

    public Parts Parts { get; set; }
}

[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Parts")]
public class Parts : IList<string>
{
    private List<string> _parts;

    public Parts()
    {
        _parts = new List<string>();
    }

    #region IList<string> Members

    public int IndexOf(string item)
    {
        return _parts.IndexOf(item);
    }

    public void Insert(int index, string item)
    {
        _parts.Insert(index, item);
    }

    public void RemoveAt(int index)
    {
        _parts.RemoveAt(index);
    }

    public string this[int index]
    {
        get
        {
            return _parts[index];
        }
        set
        {
            _parts[index] = value;
        }
    }

    #endregion

    #region ICollection<string> Members

    public void Add(string item)
    {
        _parts.Add(item);
    }

    public void Clear()
    {
        _parts.Clear();
    }

    public bool Contains(string item)
    {
        return _parts.Contains(item);
    }

    public void CopyTo(string[] array, int arrayIndex)
    {
        _parts.CopyTo(array, arrayIndex);
    }

    public int Count
    {
        get { return _parts.Count; }
    }

    public bool Remove(string item)
    {
        return _parts.Remove(item);
    }

    #endregion

    #region ICollection<string> Members


    public bool IsReadOnly
    {
        get { throw new NotImplementedException(); }
    }

    #endregion

    #region IEnumerable<string> Members

    public IEnumerator<string> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    #endregion
}

在VB6中:
Option Explicit
Dim car As New ClassLibrary1.car
Dim parts As New ClassLibrary1.parts

Private Sub Form_Load()

    parts.Add "wheel"
    parts.Add "door"
    parts.Add "hood"
    parts.Add "trunk"

    car.Name = "GAS-24"
    Set car.parts = parts
    car.parts.RemoveAt (0)
End Sub

这种方法的缺点是代码太多:(
如果有人知道类似的内容,请告诉我。
//**[MakeVisibleListInVB6]**
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("ClassLibrary1.Car")]
public class Car
{
    public Car()
    {
        Name = "";
        Parts = new Parts();
    }

    public string Name { get; set; }

    public List<string> Parts { get; set; }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接