-1

我对 c# 很陌生,这可能是一个非常菜鸟和简单的问题,我会尽力解释问题是什么:

我正在努力在类之间“引用”变量......让我解释一下情况和我需要做什么:

我有一个“节点”类,其中包含一堆变量,例如“名称”、“长度”、“XCoordinate”、“YCoordinate”、“节点类型”——它们都是我从 XML 文件中读取的字符串。

我还有一个“NodeLinkage”类,其中包含一堆字符串变量(也从 XML 文件中读取),例如“Length”、“TrackType”等等。

问题:我从一个 XML 文件中收集这些数据,并且需要编写两个文本文件(一个用于节点,一个用于链接 (NodeLinkage))。NodeLinkage 文件还需要具有与 Node 文件中相同的一些信息(例如“NodeAName”和“NodeBName”——两个“Node”对象名称)。我希望有某种方法可以在每个“NodeLinkage”中使用“指针”(或类似的东西)来引用这些特定的节点......因此存储名称(和所需的任何其他变量)更容易......

这些 XML 文件有多达 5000 个节点,以及大量的链接,并且读取 XML 文件以便首先读取节点数据,然后读取链接数据。

读取(列表/地图/字典)时存储此信息(节点和节点链接)的最佳方式是什么,以及如何使用“指针”之类的东西从链接中引用特定的节点/节点名称。


编辑!:

感谢到目前为止已经回复的人!这是正在读取的 XML 文件的示例:

<Nodes>
    <Node Name="WAI2" LongName="Waitara" Length="100" NodeType="6" ... (other attributes)>
        <NodeMasterTimingPoint NodeName="WAI1"></NodeMasterTimingPoint>
    </Node>
    <Node Name="WAI3" LongName="Waitara" Length="100" NodeType="6" ... (other attributes)>
        <NodeMasterTimingPoint NodeName="WAI1"></NodeMasterTimingPoint>
    </Node>
    .... other nodes
</Nodes>

<Links>
    <Link NodeAName="WAI1" NodeBName="WAI2" Length="200" TrackType="37" SBId="10482">
    </Link>
    ... more links
</Links>

每个节点/链接记录有大约 15-20 个属性。

如您所见,链接记录使用两个“NodeXName”......我想知道是否有任何方法可以引用或“指向”这两个节点,因此在打印链接数据时可以使用类似 NodeA.Name 的东西。因此,如果需要,也可以使用其他数据,例如 NodeA.Length。

Node Class:

class cNode
{
    public string Name;
    public string LongName;
    public string PlatformName;
    public string NodeType;
    public string Length;
    public string MasterTimingNode;
    public string MasterJunctionNode;
    public string[] PenaltyFromNode;
    public string[] PenaltyToNode;
    public string[] Penalty;
    public string PFMORI;
    public string XCRD;
    public string YCRD;
    public string PlanLocation;

    // Few methods which aren't important
    public string GetDataString()
    {
    ...
    }

}

NodeLinkage 类与上面的 Node 类非常相似。

我还有一个带有 main 方法的“main”类,它将简单地读取 XML 文件并为每个节点/链接分配值——虽然不确定如何存储这些?列表?地图?

如前所述,在读取链接数据之前读取和存储节点数据(因此创建节点对象)。

再次感谢尼克。

很抱歉有大量的东西要阅读。:P

4

2 回答 2

0

From what I can tell, "NodeType" would be an attribute of a "Node". However it is not clear what the relationship between a "Node" and a "NodeLinkage" is. I suspect this NodeLinkage is really just a way of dealing with the relationship between objects during serialization/deserialization (in case those words haven't been explained to you yet, serialization is the process of taking a set of objects in memory and persisting them to files and/or databases; deserialization is creating a set of objects from files and/or databases).

Objects in memory ("object instances") will have references to other objects; for example, your "Node" might have only a single NodeType, or it might have multiple NodeTypes. Either way, as far as your instance of a Node is concerned, NodeType (or NodeTypes) is simply a reference to another object. It doesn't matter if one or a hundred nodes all share the same node type; they will all point to the same NodeType instance -- you won't have a hundred nodes with a hundred NodeType instances.

However, when the time comes to serialize, to avoid duplicating a bunch of NodeType entries, you will want to be able to abstract a NodeType with an identifier (you will often see this called an Identity property). Before we get to the solution, let's take a look at our class structures and how they would serialize:

    public class NodeManager
    {
        public List<Node> Nodes { get; set; }
    }

    public class Node
    {
        public string Name { get; set; }
        public List<NodeType> NodeTypes{ get; set; }
        public int Length { get; set; }
        public int XCoordinate { get; set; }
        public int YCoordinate { get; set; }
    }

    public class NodeType
    {
        public string Name { get; set; }
        public string SomeOtherNodeTypeProperty { get; set; }
        public string YetAnotherNodeTypeProperty { get; set; }
    }

In this object model, the NodeManager class serves as your in-memory repository for all of the Nodes that have been instantiated. This is the class you will serialize from, or deserialize to. It contains a collection of Nodes, and nothing else. In a more detailed model, it will probably contain methods to create, add, delete and query the Node collection in useful ways, but for the purposes of discussing ser/deser this is enough.

As you can see, a Node object can have multiple types. If we were to create ten thousand Nodes in memory, each with a few types, we would have a massive duplication of the NodeType XML nodes in the written file, because the serializer has no way to abstract a NodeType instance into a reference to a NodeType. Our XML file will look something like this (not precisely like this; I did this by hand):

<?xml version="1.0" encoding="utf-8"?>
<Nodes>
    <Node>
        <Name>Foo</Name>
        <Length>5</Length>
        <XCoordinate>24</XCoordinate>
        <YCoordinate>36</YCoordinate>
        <NodeTypes>
            <NodeType>
                <Name>Type 1</Name>
                <SomeOtherNodeTypeProperty>Blah</SomeOtherNodeTypeProperty>
                <YetAnotherNodeTypeProperty>Meh</YetAnotherNodeTypeProperty>
            </NodeType>
            <NodeType>
                <Name>Type 2</Name>
                <SomeOtherNodeTypeProperty>Foo</SomeOtherNodeTypeProperty>
                <YetAnotherNodeTypeProperty>Bar</YetAnotherNodeTypeProperty>
            </NodeType>
            <NodeType>
                <Name>Type 3</Name>
                <SomeOtherNodeTypeProperty>Fizz</SomeOtherNodeTypeProperty>
                <YetAnotherNodeTypeProperty>Buzz</YetAnotherNodeTypeProperty>
            </NodeType>
        </NodeTypes>
    </Node>
    <Name>Bar</Name>
    <Length>15</Length>
    <XCoordinate>224</XCoordinate>
    <YCoordinate>336</YCoordinate>
    <NodeTypes>
        <NodeType>
            <Name>Type 1</Name>
            <SomeOtherNodeTypeProperty>Blah</SomeOtherNodeTypeProperty>
            <YetAnotherNodeTypeProperty>Meh</YetAnotherNodeTypeProperty>
        </NodeType>
        <NodeType>
            <Name>Type 2</Name>
            <SomeOtherNodeTypeProperty>Foo</SomeOtherNodeTypeProperty>
            <YetAnotherNodeTypeProperty>Bar</YetAnotherNodeTypeProperty>
        </NodeType>
        <NodeType>
            <Name>Type 3</Name>
            <SomeOtherNodeTypeProperty>Fizz</SomeOtherNodeTypeProperty>
            <YetAnotherNodeTypeProperty>Buzz</YetAnotherNodeTypeProperty>
        </NodeType>
    </NodeTypes>
    </Node>
</Nodes>

Notice how the two nodes each support 3 Node types, and they are complete duplicates of each other. To avoid this we can add a NodeTypeID property. This is simply a value that is guarenteed to be unique across all NodeType instances. When we have that, instead of having to write out an entire NodeType, we can just write it's ID, and from the ID we can get to the rest of the information about a NodeType. Let's add a new property to our NodeType :

public class NodeType
{
    public int NodeTypeId { get; set; }
    public string Name { get; set; }
    public string SomeOtherNodeTypeProperty { get; set; }
    public string YetAnotherNodeTypeProperty { get; set; }
}

Now that there is a NodeTypeID property when we serialize our nodes, it looks a lot cleaner:

<?xml version="1.0" encoding="utf-8"?>
<NodeRoot>
    <Nodes>
        <Node>
            <Name>Foo</Name>
            <Length>5</Length>
            <XCoordinate>24</XCoordinate>
            <YCoordinate>36</YCoordinate>
            <NodeTypes>
                <NodeType NodeTypeId="1"/>
                <NodeType NodeTypeId="2"/>
                <NodeType NodeTypeId="3"/>
            </NodeTypes>
        </Node>
        <Node>
            <Name>Bar</Name>
            <Length>15</Length>
            <XCoordinate>224</XCoordinate>
            <YCoordinate>336</YCoordinate>
            <NodeTypes>
                <NodeType NodeTypeId="1"/>
                <NodeType NodeTypeId="2"/>
                <NodeType NodeTypeId="3"/>
            </NodeTypes>
        </Node>
    </Nodes>
    <NodeTypes>
        <NodeType>
            <Name>Type 1</Name>
            <SomeOtherNodeTypeProperty>Blah</SomeOtherNodeTypeProperty>
            <YetAnotherNodeTypeProperty>Meh</YetAnotherNodeTypeProperty>
        </NodeType>
        <NodeType>
            <Name>Type 2</Name>
            <SomeOtherNodeTypeProperty>Foo</SomeOtherNodeTypeProperty>
            <YetAnotherNodeTypeProperty>Bar</YetAnotherNodeTypeProperty>
        </NodeType>
        <NodeType>
            <Name>Type 3</Name>
            <SomeOtherNodeTypeProperty>Fizz</SomeOtherNodeTypeProperty>
            <YetAnotherNodeTypeProperty>Buzz</YetAnotherNodeTypeProperty>
        </NodeType>
    </NodeTypes>
</NodeRoot>

This is getting pretty long so I'll wrap it here; hopefully I've given you the direction you're looking for.

于 2012-10-31T01:17:16.817 回答
0

听起来您只想将“Node”类型的变量添加到 NodeLinkage 类中,然后在读取 XML 文件时分配它

然后所有相关的节点信息将通过对相应节点的引用提供给 NodeLinkage 类

我想这取决于节点链接可以引用多少个节点,您可以硬编码几个引用,例如

class NodeLinkage 
{
    public Node NodeA { get; set; }
    public Node NobeB { get; set; }
}

或持有一个字典/列表

class NodeLinkage 
{
    public List<Node> Nodes { get; set; }
}

听起来你也需要建立你的节点列表

List<Node> Nodes = new List<Node>();
// Read node data
Nodes = SomeRoutineThatGetsThem();

List<NodeLinkage> Links = new List<NodeLinkage>();
// Read link data
Links = SomeRoutineThatGetsThem2();

// Create node linkage refs
foreach(var link in Links) 
{
    // Find the nodes that should be associated with this link - maybe using Linq?
    var assocNodes = Nodes.Where(n => n.NodeID == link.NodeID); // No idea what your setup is so this is a random pseudo code bit!
    // blah - assign etc
}

到目前为止,这对您有用吗?

于 2012-10-31T00:39:43.577 回答