-1

私はc#に非常に慣れていないので、これはおそらく非常に初心者で単純な質問です。問題が何であるかを説明するために最善を尽くします。

クラス間で変数を「参照」するのに苦労しています...状況と私がする必要があることを説明しましょう:

「Name」、「Length」、「XCoordinate」、「YCoordinate」、「NodeType」などの変数のヒープを含む「Node」クラスがあります。これらはすべてXMLファイルから読み取っている文字列です。

また、「Length」、「TrackType」などの文字列変数(XMLファイルからも読み取られる)を含む「NodeLinkage」クラスもあります。

問題:XMLファイルからこのデータを収集しており、2つのテキストファイル(1つはノード用、もう1つはリンク(NodeLinkage)用)を書き込む必要があります。NodeLinkageファイルには、Nodeファイルと同じ情報の一部(「NodeAName」や「NodeBName」など、「Node」オブジェクト名の2つ)も必要です。私は、これらの特定のノードを参照する各「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の属性があります。

ご覧のとおり、リンクレコードは2つの「NodeXName」を使用しています...これらの2つのノードを参照または「ポイント」する方法があるかどうか疑問に思っていたため、リンクデータを出力するときに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

「ノード」タイプの変数を 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 に答える