因此,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();
}
}