0

在我的应用程序中,我使用 mpxj 从 microsoft 项目文件中提取项目 - 我需要的项目之一是前辈。我能够拉出前任的方法是使用 mpxj 的内置函数,它返回一种 java.util.list - 我可以将它作为对象保存到变量中,但我需要找到一种方法将数据带到一种我可以轻松使用的格式,因此我可以将其存储到数据库中。下面列出的是我用来从项目文件中提取前辈的代码行。

Dim predecessors = task.getPredecessors

这是放入跟踪点以获取前辈值时的结果

[[Relation [Task id=4 uniqueID=45577 name=Standards Training - Round 2] -> [Task id=3 uniqueID=45576 name=Process Excellence Training]]]

即使我可以将上述内容作为字符串获取,我也可以使用它来获取我需要的数据。上面的例子是前置列表中有 1 个项目,但有时有多个项目。以下是有多个项目时的跟踪点示例。

[[Relation [Task id=63 uniqueID=45873 name=Complete IP Binder] -> [Task id=47 uniqueID=45857 name=Organizational Assessment]], [Relation [Task id=63 uniqueID=45873 name=Complete IP Binder] -> [Task id=49 uniqueID=45859 name=Document Deliverables]], [Relation [Task id=63 uniqueID=45873 name=Complete IP Binder] -> [Task id=56 uniqueID=45866 name=Infrastructure Deliverables]], [Relation [Task id=63 uniqueID=45873 name=Complete IP Binder] -> [Task id=58 uniqueID=45868 name=IT Deliverables]], [Relation [Task id=63 uniqueID=45873 name=Complete IP Binder] -> [Task id=60 uniqueID=45870 name=Organizational Deliverables]]]

谢谢您的帮助。

4

3 回答 3

4

在 C# 3.5+ 中,创建一个扩展方法来为这些 Java 列表提供一个漂亮的、类型安全的枚举器非常容易,因为有yield关键字。你可以这样做:

public static class JavaExtensions
{

        public static IEnumerable<T> toIEnumerable<T>(this java.util.List list)
        {
            if (list != null)
            {
                java.util.Iterator itr = list.iterator();

                while (itr.hasNext())
                {
                    yield return (T)itr.next();
                }
            }
        }

}

只要包含此扩展的命名空间对您的代码可见,那么您只需执行以下操作即可使用前辈:

foreach (var relation in task.getPredecessors().toIEnumerable<Relation>())
{
   Task sourceTask = relation.getSourceTask();
   //etc.
}

不幸的是,您使用的是 VB.Net。我和你在同一条船上,最后制作了一个单独的 C# 类库,我在我的 VB ASP.NET 项目中引用了它。这样,我就可以在处理 IKVM Java 样式对象时获得 C# 语法的好处,而无需转换我的整个项目。

如果您不想这样做,您可以使用在线代码转换器将 Jon 的代码(不使用任何 C#-only 功能)更改为 VB 并将其包含在您的项目中。

上述情况的主要内容是,您不需要使用在调试器中看到的字符串表示形式(这只是在该列表中的 Relation 对象上调用 toString() )。该getPredecessors()函数正在返回一个Relation对象列表。

Dim predecessorList as java.util.List = task.getPredecessors()
Dim iter as java.util.Iterator = predecessorList.iterator()

Do While iter.hasNext()
    Dim curRelation as Relation = iter.next()

    'gets the left side of the relationship (the task you are dealing with)
    Dim sourceTask as Task = curRelation.getSourceTask()

    'gets the task that is the predecessor to the  'source' task
    Dim targetTask as Task = curRelation.getTargetTask()

    'from here you can call methods on the Task objects to get their other properties
    'like name and id
Loop
于 2012-03-19T18:07:45.903 回答
1

使用由 IKVM 生成的 .Net 程序集时,有两种处理 Java 集合的方法。第一个是用 Java 方式做事并使用迭代器:

java.util.List predecessors = task.getPredecessors();
java.util.Iterator iter = predecessors.iterator();
while (iter.hasNext())
{
   Relation rel = (Relation)iter.next();
   System.Console.WriteLine(rel);
}

另一种方法是添加一些“可用性”代码来隐藏它:

foreach(Relation rel in ToEnumerable(task.getPredecessors()))
{
   System.Console.WriteLine(rel);
}

为此,我创建了“ToEnumerable”方法:

private static EnumerableCollection ToEnumerable(Collection javaCollection)
{
   return new EnumerableCollection(javaCollection);
}

和 EnumerableCollection 类,它隐藏了迭代器的使用:

class EnumerableCollection
{
    public EnumerableCollection(Collection collection)
    {
        m_collection = collection;
    }

    public IEnumerator GetEnumerator()
    {
        return new Enumerator(m_collection);
    }

    private Collection m_collection;
}


public struct Enumerator : IEnumerator
{
    public Enumerator(Collection collection)
    {
        m_collection = collection;
        m_iterator = m_collection.iterator();
    }

    public object Current
    {
        get
        {
            return m_iterator.next();
        }
    }

    public bool MoveNext()
    {
        return m_iterator.hasNext();
    }

    public void Reset()
    {
        m_iterator = m_collection.iterator();
    }

    private Collection m_collection;
    private Iterator m_iterator;
}

一个更有趣的方法是使用扩展方法将此功能添加到 java Collection 类中,这将使您的代码不那么混乱。我计划在下一个版本中尝试发布一个包含有用扩展方法的程序集,作为 MPXJ 的一部分。

于 2012-03-19T13:34:13.680 回答
0

能够通过使用 tostring 然后左右来完成此操作,以更快地删除我需要的内容-不知道为什么之前将其删除

于 2012-03-22T17:12:07.667 回答