質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

パース

パースとは、一定の文法に従って記述されたテキスト文書を解析し、データ構造の集合体に分解・変換することを呼びます。

Q&A

解決済

3回答

6525閲覧

C# DXFのパーサ自作 クラスか構造体か

ElecDove

総合スコア254

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

パース

パースとは、一定の文法に従って記述されたテキスト文書を解析し、データ構造の集合体に分解・変換することを呼びます。

0グッド

0クリップ

投稿2017/06/11 04:34

お世話になっております.

現在,C#(WPF)を使ってDXFファイル(2DCADのファイル形式)のパースをするプログラムを作っています.

2DCADですから線分や円弧等が非常に大量に(数百~数万)登場します.
今は,これらすべての図形に対して一つ一つオブジェクトとみなしてインスタンスを作っているのですが,一つ一つのオブジェクト自体は非常に軽量です(線分なら,始点と終点,色,線分の種類,レイヤー程度の情報しかないため)

このような用途は構造体のほうが適しているのではと思い質問させていただきました

しかし,構造体にすると継承ができません.

例えば,色や線の種類(実線,破線,点線等)はすべての図形が共通に持つ情報ですし,基底クラスにこれら共通部分を定義してしまうのがいいのかな?とも思っている次第です.

抽象的な質問ではありますが,アドバイスいただけたらと思います.

コーディング途中ですが,読み込んだDXFを最終的に一つの大きなオブジェクトとするので,そのひな型を下に示します.(一部抜粋)

正直このようなひな型の作り方が正しいのかどうかもわかりません....
以前,XMLSerializerを使ったことがあるので,その時に作ったひな型と同じように作っています.
しかし,例えばひな型の中に,変数だけではなくクラスを一緒に作っていますが,それが良いかもわかりません.

何か引っかかるものを感じましたらアドバイスいただけると助かります.

よろしくお願いいたします.

C#

1 2 /// <summary> 3 /// DXFをパースするときのひな型 4 /// </summary> 5 public class DxfFormat { 6 public enum SectionIdList {HEADER, TABLES, BLOCKS, ENTITIES, CLASS}; 7 8 public HeaderClass Header = new HeaderClass(); 9 public class HeaderClass { 10 public enum VersionList { AC1003, AC1006, AC1009, AC1012, AC1014, OTHER }; 11 public VersionList Version = VersionList.OTHER; 12 13 public enum MeasurementList{ INCH, METER } 14 public MeasurementList Measurement = MeasurementList.INCH; 15 16 public Point3D Limmin = new Point3D(); //図面の最小値 17 public Point3D Linmax = new Point3D(); //図面の最大値 18 public int DIMSCALE; //寸法の尺度 19 public int PEXTMIN; //ペーパー空間のオブジェクトの最小値 20 public int PEXTMAX; //ペーパー空間のオブジェクトの最大値 21 public string Dwgcodepage; //図面のコードページ日本語はR13Jまで "dos932"、R14から"ANSI_932"です。 22 } 23 24 public TableClass Table = new TableClass(); 25 public class TableClass { 26 /// <summary> 27 /// LineType 28 /// </summary> 29 public class LineType { 30 public string Name; 31 public string Description; 32 public double PatternLong; //1パターン当たりの長さ 33 public int numOfDashes; //その線はどのような線から構成されるかの個数 GroupCode = 73 34 public List<double> Dashes = new List<double>(); 35 } 36 public List<LineType> LineTypeList = new List<LineType>(); 37 public int numOfLines; 38 39 /// <summary> 40 /// Layer 41 /// </summary> 42 public class LayerType { 43 public string Name; 44 public int Color; 45 } 46 public List<LayerType> LayerTypeList = new List<LayerType>(); 47 public int numOfLayers; 48 } 49 50 //このリストに図形を全部放り込んでいく. 51 public List<EntityBaseClass> Entities = new List<EntityBaseClass>(); 52 53 /// <summary> 54 /// Entityの基底クラス. 55 /// </summary> 56 public class EntityBaseClass { 57 public string LayerName; 58 } 59 60 public class EntityLineClass : EntityBaseClass { 61 public Point Start = new Point(); 62 public Point End = new Point(); 63 public string LineType; 64 } 65 66 public class EntityArcClass : EntityBaseClass { 67 public Point Center = new Point(); 68 public double Radius; 69 public double StartDegree; 70 public double EndDegree; 71 } 72 73 public class EntityCircleClass : EntityBaseClass { 74 public Point Center = new Point(); 75 public double Radius; 76 } 77 } 78 } 79

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

すでに解決済みになっていますが、CodeProjectにC#でのサンプルありましたので参考になるかと思います。
DXF Import .NET: Read and View AutoCAD Format Files

投稿2017/06/14 07:28

can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

投稿するの忘れていました…(一応投稿しておきます)


構造体を効果的に使うのは難しいです。
構造体が何かよくわからないならクラスにしておいた方が良いです。
事前によく構造体の仕組みを勉強してから使い始めましょう。

構造体にするオブジェクトは以下にハマっている場合だけでいいと思います。

・プリミティブ型に似ている(intとかdoubleみたいな。例えばカラーコード。)
・サイズが16バイト以下である
・イミュータブルである
・あまりBOX化されない

これはMSDNで提示されている指針です。

より言語化した指針を上げるなら以下のような条件を満たすものは構造体に適しています。
・ある一つの情報を表す
・オブジェクトとして識別される必要がない

例えば、あるお店の情報は識別される必要がありますが、座標情報は識別される必要はありませんね。
提示されてるサンプルコードの場合、Point、Point3D、Color、Degreeは構造体でも良いでしょう。
線分については、始点や終点だけを変更する必要がある場合は微妙です。
これは、ある線分を識別し、その情報の一部を修正することになりますから、クラスに適していると私なら考えます。

例外もありますけどね。
例えばクラスのフィールドに使う場合で、外部に公開されない構造体なら上記のルールは守らなくても良いです。
値のコピーも簡単ですし、ミュータブルな情報をクローンしたい時なんて結構ありますからね。

後はー…Parserを書くなら一度Roslynに目を通しておいても損はないです。
僕は文脈に分解する機能と、文脈を各オブジェクト種別に変換するメソッドのMapperで構成するのが好みです。

投稿2017/06/14 07:11

編集2017/06/14 07:12
haru666

総合スコア1591

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

数百~数万という規模は大量といえば大量ですが、「そうでもない」と思える規模だとも思います。それをclassではなくstructとする必要はないというのが自分の意見です。(読み込んだDXFをどのように扱うかにもよると思いますが・・・)

クラスと構造体

こうしたページが「どちらにするかの根拠の明確化」に役立つと思います。


ちなみに、現時点ではコンストラクターもオペレーションも特に定義されていないので、これらのクラスをどう設計することを意図しているかわかりません。自分ならパース用のstaticメソッドを各クラスへ置きますが・・・


ところでメンバーの中には外部から更新不可としたほうがよいものがあるのではないでしょうか?
多分、本件の質問意図からは外れると思いますが・・・

投稿2017/06/11 07:06

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ElecDove

2017/06/12 13:09

回答ありがとうございます. >「そうでもない」と思える規模 もっと大量のオブジェクトを扱うことも普通にあると言うことなんですね >classではなくstructとする必要はないというのが自分の意見 明快な回答ありがとうございます.リンク先も参考にさせていただきます. >自分ならパース用のstaticメソッドを各クラスへ置きますが・・・ ごめんなさい,理解できなかったです.もう少し詳しく教えていただけますでしょうか 現状の処理としては,パーサメソッドがDXFを一行ずつ読み取り,必要なデータを見つける毎にDxfFormatの中に整理して突っ込んでいる状態です. >ところでメンバーの中には外部から更新不可としたほうがよいものがあるのではないでしょうか? はい,おっしゃるとおりです 生成したDXFのオブジェクトに対してパーサ以外(データを使う側)から変更することはないため,すべてのメンバ変数は読み取り専用でいいくらいです,がまずはパーサを作ることを優先してしまったので,こうなっています やはり,プロパティ?によるアクセスにしたほうが良いのでしょうか (もし違う意図で回答いただいていたらごめんなさい)
KSwordOfHaste

2017/06/12 13:19

> 外部から更新不可としたほうがよいものがある > パース用のstaticメソッドを各クラスへ置きます クラスAに外部から変更不可(readonly)の属性があるなら、クラスAのロード処理を外部のクラスで行うより、A自身のメソッドがやると(あらゆるメンバーに自由にアクセスできるので)作りやすいと考えたまでです。
ElecDove

2017/06/12 13:53

>クラスAのロード処理を外部のクラスで行うより、A自身のメソッドがやると なるほど!!そういうことでしたか 以前使用したXMLSerializerが雛形を外部クラスで作るタイプのものだったのでそれと同じようにやっていました DXFの雛形自体は自由に生成する必要はないので,そのほうがいいのかもしれません ところでバージョン違いによるデータ構造の差もクラスの継承で実現できそうでしょうか (今まではたとえばR12バージョンはDxfFormat_R12クラスをわたして,R14バージョンだったらDxfFormat_R14を渡して,というイメージでやっていました)
KSwordOfHaste

2017/06/12 15:56

> バージョン違い DXFの詳細を知らないのでR12とかR14といったバージョンの違いがどの程度の違いかがわかりません。違いが大きければバージョンにより違うクラスに切り替える方が分かり易いと思います。
ElecDove

2017/06/13 02:20

ファイル構造は基本的に変わらず,項目の数が増えている感じになります 色々試してみたいと思います 貴重なアドバイスありがとうございました
KSwordOfHaste

2017/06/13 02:25

> 項目の数が増えている なるほど・・・ その項目をnullのままにしておくことで単一クラスで扱うこともできなくはないでしょうが、R12に項目がなくてR14に項目が追加されているといった感じならば、R12用のクラスの派生をR14とするのが一番素直な感じがしますね!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問