【问题标题】:converting values of java.util.list to string or other normal format in vb在 vb 中将 java.util.list 的值转换为字符串或其他正常格式
【发布时间】:2012-03-31 06:54:00
【问题描述】:

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

Dim predecessors = task.getPredecessors

这里是放一个tracepoint获取前辈值的结果

[[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]]]

感谢您的帮助。

【问题讨论】:

    标签: asp.net vb.net ms-project mpxj


    【解决方案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;
    }
    

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

    【讨论】:

    • 你不知道它救了我多少命!谢谢。
    【解决方案2】:

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

    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# 语法的好处,而无需转换我的整个项目。

    如果您不想这样做,您可以使用an online code converter 将 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
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 它现在可能对你有用,但不能保证 toString() 的输出将永远保持不变。它实际上只是作为一种在调试时快速查看对象内容的某些识别方面的方法(注意它不包括关系的 Type 或 Lag 值)。为了将来维护您的代码的人,我建议您学习按预期使用 api,尤其是当您从 toString 输出解析这些任务的各个属性时。
      猜你喜欢
      • 1970-01-01
      • 2011-08-26
      • 2020-10-22
      • 1970-01-01
      • 1970-01-01
      • 2014-03-25
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多