因此,SOLIDWORKS PDM API实现了一种奇怪的方式来存储字符串数组。而不是将其存储在简单的简单string []中,而是有一个名为IEdmStr5的接口,用于存储任意字符串的列表。我不知道其背后的设计原因,但我的猜测与组件对象模型的内部特性有关。与IEdmPos5接口一起,您可以遍历字符串列表。以下是遍历配置名称列表的示例:

private bool IsConfigInList(IEdmStrLst5 ConfigNames, string ConfigName)
    {
        bool functionReturnValue = false;
        functionReturnValue = false;
        try
        {
            string CurConfig = null;
            IEdmPos5 Pos = ConfigNames.GetHeadPosition();
            while (!Pos.IsNull)
            {
                CurConfig = ConfigNames.GetNext(Pos);
                if (CurConfig == ConfigName)
                {
                    functionReturnValue = true;
                    break;
                }
            }
            return functionReturnValue;
        }
        catch (System.Runtime.InteropServices.COMException ex)
        {
            Interaction.MsgBox("HRESULT = 0x" + ex.ErrorCode.ToString("X") + Constants.vbCrLf + ex.Message);
        }
        catch (Exception ex)
        {
            Interaction.MsgBox(ex.Message);
        }
        return functionReturnValue;
    }


我试图在我的单元测试中使用这些接口来模拟它们。这是我的尝试:

        // test
        public static void PrintmEdmStrLst5_Test()
        {

            var mStrList = new CADSharpTools.PDM.Testing.mEdmStrLst5(new string[] { "Element 1", "Element 2", "Element 3" });
            var mPos = mStrList.GetHeadPosition();
            while (mPos.IsNull == false)
            {
                Console.WriteLine(mStrList.GetNext(mPos));

            }
        }

public class mEdmPos5 : IEdmPos5
    {
        int pos = -1;

        public int GetIndex()
        {
            return pos;
        }

        public mEdmPos5(int Pos)
        {
            pos = (int)Pos;
        }

        public IEdmPos5 Clone()
        {
            return new mEdmPos5(this.pos);
        }

        /// <summary>
        /// Gets whether the position in the sequence is null or not.
        /// </summary>
        public bool IsNull =>  this.pos <= -1 ? true : false ;
    }
    public class mEdmStrLst5 : IEdmStrLst5
    {
        mEdmPos5 currentPosition = default(mEdmPos5);
        int counter = 0;
        int count = 0;
        List<string> innerList = new List<string>();
        List<mEdmPos5> innerPositions = new List<mEdmPos5>();

        public mEdmStrLst5(string[] arr)
        {
            innerList.AddRange(arr);
            count = arr.Length;
            for (int i = 0; i < count; i++)
            {
                innerPositions.Add(new mEdmPos5(i));
            }


        }

        public void AddTail(string bsString)
        {
            innerList.Add(bsString);
            count = innerList.Count;
        }

        /// <summary>
        /// Get the first position. Calling this method will reset the counter to 0.
        /// </summary>
        /// <returns></returns>
        public IEdmPos5 GetHeadPosition()
        {
            currentPosition = innerPositions[0];
            counter = 0;
            return currentPosition;
        }

        /// <summary>
        /// Returns the next str in the list.
        /// </summary>
        /// <param name="poPos"></param>
        /// <returns></returns>
        public string GetNext(IEdmPos5 poPos)
        {
            var clonedPosition = currentPosition.Clone();
            if (counter == innerList.Count-1)
            {
                currentPosition = new mEdmPos5(-1);
                poPos = currentPosition;
                return null;
            }
            counter = counter + 1;
            currentPosition = innerPositions[counter];
            poPos = currentPosition;
            return innerList[(clonedPosition as mEdmPos5).GetIndex()];

        }

        /// <summary>
        /// Returns whether the string list is empty or not.
        /// </summary>
        public bool IsEmpty => innerList.Count == 0 ? true : false;


        /// <summary>
        /// Returns the size of the list.
        /// </summary>
        public int Count => innerList.Count;
    }


上面的所有代码都在C#中。我的挣扎似乎与GetNext()有关。似乎应该传递mPos作为参考,否则,如何进行迭代?

以下是两个接口的定义:

public interface IEdmPos5
    {
        [DispId(2)]
        IEdmPos5 Clone();

        [DispId(1)]
        bool IsNull { get; }
    }
public interface IEdmStrLst5
    {
        [DispId(3)]
        void AddTail(string bsString);
        [DispId(4)]
        IEdmPos5 GetHeadPosition();
        [DispId(5)]
        string GetNext(IEdmPos5 poPos);

        [DispId(1)]
        bool IsEmpty { get; }
        [DispId(2)]
        int Count { get; }
    }


非常感谢您的帮助!

最佳答案

您可以将其包装在IEnumerator周围,因为IEdmPos5代表枚举器

class Program
{
    static void Main(string[] args)
    {
        IEdmStrLst5 strLst = new EdmStrLstWrapper(new List<string>(new string[] { "A", "B", "C" }));

        var pos = strLst.GetHeadPosition();
        while (!pos.IsNull)
        {
            Console.WriteLine(strLst.GetNext(pos));
        }
    }
}

public class EdmStrLstWrapper : IEdmStrLst5
{
    private readonly List<string> m_List;

    public EdmStrLstWrapper(List<string> list)
    {
        if (list == null)
        {
            throw new ArgumentNullException(nameof(list));
        }

        m_List = list;
    }

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

    public bool IsEmpty
    {
        get
        {
            return m_List.Count == 0;
        }
    }

    public void AddTail(string bsString)
    {
        m_List.Add(bsString);
    }

    public IEdmPos5 GetHeadPosition()
    {
        var pos = new EdmPosWrapper(m_List.GetEnumerator());
        pos.MoveNext();

        return pos;
    }

    public string GetNext(IEdmPos5 poPos)
    {
        if (poPos is EdmPosWrapper)
        {
            var val = (poPos as EdmPosWrapper).Current;
            (poPos as EdmPosWrapper).MoveNext();
            return val;
        }
        else
        {
            throw new NotSupportedException();
        }
    }
}

public class EdmPosWrapper : IEdmPos5
{
    private readonly IEnumerator m_Enumerator;

    private bool m_IsLast;

    public EdmPosWrapper(IEnumerator enumerator)
    {
        m_Enumerator = enumerator;
    }

    public bool IsNull
    {
        get
        {
            return m_IsLast;
        }
    }

    public IEdmPos5 Clone()
    {
        return new EdmPosWrapper(m_Enumerator);
    }

    internal string Current
    {
        get
        {
            return m_Enumerator.Current as string;
        }
    }

    internal void MoveNext()
    {
        m_IsLast = !m_Enumerator.MoveNext();
    }
}

09-25 16:45