【问题标题】:Implementing IEdmStrLst5 and IEdmPos5 - SOLIDWORKS PDM API实施 IEdmStrLst5 和 IEdmPos5 - SOLIDWORKS PDM API
【发布时间】:2019-02-11 09:01:16
【问题描述】:

因此,SOLIDWORKS PDM API 实现了一种存储字符串数组的奇怪方式。不是将它存储在简单的字符串 [] 中,而是有一个名为 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; }
    }

我们将非常感谢您的帮助!

【问题讨论】:

    标签: c# solidworks


    【解决方案1】:

    你可以把它包裹在 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();
        }
    }
    

    【讨论】:

    • 谢谢!使用 IEdmPos5 实现 IEnumerator 是有意义的!
    猜你喜欢
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 2017-06-05
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多