4

解析する必要のあるファイル形式は次のようになります。

v1|000|sammy|endpoint|blah

これはベンダーが提供する順序付きの固定幅形式であるため、これら5つのフィールドのそれぞれがクラス内の特定のプロパティにマップされます(実際の形式は> 30です)。

プロパティにシーケンスを適用して、Reflectionでこれを解析したいと思います。これを行う1つの方法は、自分で何かを作成することです。単一の数値を受け取るAttributeクラスを記述し、その属性をそのシーケンスインデックスとともに各プロパティに適用し、OrderBy句のReflection中にそれを探します。

C#でこれを行うための既存のまたはより良い方法はありますか?たとえば、これにはすでに属性がありますか?クラスで宣言された順序プロパティをC#またはMSILで尋ねる方法はありますか?

4

7 に答える 7

4

プロパティがメタデータに表示される順序は、を使用して表示できますPropertyInfo.MetadataToken。現在のコンパイラは、この順序をソースコードに表示されるプロパティの順序と一致させることがあります。したがって、で順序付けすることにより、ソースコードMetadataTokenと同じ順序になります。

免責事項:将来のコンパイラはこれを変更する可能性があります。理由がなければおそらくそうはなりませんが、たとえばコンパイラがマルチスレッドになると、元の順序を維持するために余分な不必要な労力がかかる可能性があります。これに依存している場合は、.NET Frameworkが更新されてこれが機能しなくなった場合に、サイレントランタイムの破損ではなく、ハードエラーが発生することを確認してください。

于 2012-07-09T21:22:27.460 に答える
1

属性ベースのアプローチを使用したい場合は、個人的に、このためのカスタム属性を作成します。これは「標準」操作ではないため、クラスを装飾するために使用できる(適切な)属性はフレームワークにありません。

私のアプローチはおそらくクラスレベルの属性であり、リスト内のエントリごとにプロパティ名の文字列の配列、またはそれらの行に沿ったものを受け入れます。

そうは言っても、属性ベースのアプローチが正しいアプローチであるかどうかは疑問です。「リフレクション」プロセスを実行する必要があるため、これを仲介するある種のマネージャークラスが必要になる可能性があります。特に、クラス階層の知識がすでに必要になるため(最初にクラスを構築するために)、そのクラスにここでの関係を管理させる方が理にかなっている場合があります。

その時点で、オブジェクトを直接構築できるカスタムクラスまたはメソッドを使用すると、リフレクションを使用してこれを動的に実行するよりも、パフォーマンスが向上し、保守が容易になり、はるかに簡単になります。

于 2012-07-09T16:26:25.303 に答える
1

.net 4.0を使用していますか?これは、動的キーワードが作成されたまさにそのような状況のようです。つまり、順序と一貫性は、特定のタイプがどの時点で発生するかよりも重要であるように思われるため、動的オブジェクトにタイトルやデータなどを任意に割り当てて、それらを引き抜くことができます。同じルールを使用します。これにより、(おそらく)リフレクションを使用しないようになります。これは常にプラスです。

于 2012-07-09T16:28:49.627 に答える
1

FileHelpersのようなものを使用して解析することをお勧めします。

于 2012-07-09T16:39:17.450 に答える
1

ここで、パフォーマンスが大きな問題ではなく、Reflectionを使用する場合、属性なしでマッピングを取得する簡単な方法は、グループを使用してRegExを使用して解析することです。この実装と同様: テキストファイルから固定幅のレコードを読み取ります

次のような正規表現を使用します。

"^(?<Field1>.{6})(?<Field2>.{16})(?<Field3>.{12})"

グループ名は自分で定義できるため、プロパティ名と正確に一致する名前を賢く選択できます。そうすれば、属性を使用せずに、Reflectionを使用して自動的にマップできます。

編集: 文字列内にプロパティ名が含まれることになり、これはあまり「リファクタリングに適した」ものではないことを考えると、プロパティの名前を変更すると不一致が生じたときにテストが失敗することを確認するために、これを徹底的に単体テストすることを強くお勧めします。

于 2012-07-09T16:43:50.223 に答える
0

GoogleのProtocolBuffersに似たものを実装することを検討できます。

現在(私が知っている)C#の実装はありませんが、提供されているドキュメントは非常に優れており、はるかに遅く、通常は複雑なリフレクションよりもパフォーマンスが優れているアイデアを提供するはずです。

于 2012-07-09T16:35:55.167 に答える
0

もちろん、ここには多くの可能な答えがあるので、ここに私が出くわしたまあまあの答えがあります:

System.ComponentModel.DataAnnotationsには、ColumnAttributeという名前の既存の属性があります(.Net 4.5以降では、System.ComponentModel.DataAnnotations.Schemaに移動されます)。

http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.schema.columnattribute(v=vs.110

次のように使用できます。

[Column(Order=1)]
public string Version { get; set; }

[Column(Order=2)]
public string Id { get; set; }

ただし、固定幅の形式が変更された場合、これを更新するのは明らかに面倒です。たとえば、フィールドが最初に追加された場合は、手動で入力して、入力した30以上の序数を変更する必要があります。このシナリオではフォーマットを制御せず、将来のバージョンが頻繁に発生する可能性があるため、プロパティがクラスに入力された順序から暗黙のシーケンスを持つものを見つけると便利です。

于 2012-07-09T18:59:35.080 に答える