一般的なタイプコンバータを作成しようとしています。すべてのタイプは基本クラスがEntity
、インターフェイスがIConvertable
です。私は変換することができ、オブジェクトのためのインタフェースを実装しました:Generic Typesで静的呼び出しを置き換える正しい構造体は何ですか?
public interface IConvertable
{
public bool CanConvert<TTarget>() where TTarget : Entity, IConvertable
Tuple<bool, Entity> TryConvertTo<TTarget> where TTarget: Entity, IConvertable
}
アイデアは、エンティティの各特定のサブクラスは(partial
クラスは、自動生成されたコードは、私が直接変更することはできません)CanConvert<TTarget>
を持っているということです、ターゲットタイプに変換できるかどうかを判断します。
私はそれらを変換する(そして、同時に他のタスクを実行する - 他のインタフェースを介して、たとえば、親を変更)、一緒にEntity
のIEnumerable
秒かかりますジェネリック型コンバータを、入れしようとしていたし、その後Entity
変換返しますクラス。
私の最初の実現は、それは常にからTSource
TTarget
に一定であるという点で効果的に、CanConvert<TTarget>
は、static
である、ということでしたので、私は私のコンバータビルドするとき:明らか
public class EntityConverter<TSource, TTarget> where TSource : Entity, IConvertable
where TTarget : Entity, IConvertable
{
private IEnumerable<TSource> Records { get; set; }
public EntityConverter(IEnumerable<TSource> records) {
if (!TSource.CanConvert<TTarget>()) {
// error condition, reporting, etc.
}
Add(records);
}
public void Add(IEnumerable<TSource> records) { ... }
public void Convert() {
// massively simplified for example - there will actually be a store
// holding, more functionality, parent-child relationships, but
// this is the basic principle
for (var c in convertables) {
c.TryConvertTo<TTarget>();
}
}
}
を、多くの理由がありますstatic
関数をジェネリックで使用することはできません(Eric Lippertsの優秀な説明はonhisblogです)しかし、これは私を過酷な状態に陥ります。タイプ(Not Instance)を記述し、タイプ、一般的な構造で、大規模な外部partial
構造体または悪質なファクトリ - これは、インターフェイス実装で単にpartial
型を拡張することによって、誰かが別のクラスから呼び出すことができる、拡張可能で再利用可能な構造体であると考えられています。
私は物事を間違った方向に見ていると思われますが、何が見えないのでしょうか。どのようにタイプ変換が有効かどうかを判断するには、中間にタイプ変換を保持する必要はありませんか?
edit コードサンプルを少し前に更新しました(以前はコンストラクタで変換されていました)。実際に変換する前に、コンバート可能な複数のソースを追加する必要があるため、実際にはこのプロセスでかなり後で変換を行います。この結果、実際のエラー(If !CanConvert<TTarget>()
)がかなり下がってしまいます。このクラスの各インスタンス化では、タイプTSource
からTTarget
への変換が行われるため、コンバーターの有効性をコンストラクターに知らせる必要があります。後で変換するのではなく、コンストラクターでエラーが発生します。少なくともそれは物事についての私の読書です。
私の考えを明確にしてくれたおかげで...とにかくこれを再構築することになるかもしれませんが、私は遠く離れているとは感じません。私はのチェックをAdd()
の機能の中に入れようと考えていました...私はそこにいるように感じます...
'convertables'の各インスタンスで' CanConvert'を呼び出すだけで何が問題になりますか? 'TBase'は' TSerething'に変換できないかもしれないので、 'TDerived:TBase'は' TBase'です。 –
サイドノート:タプルは使用しないでください。 'bool TryConvertTo(エンティティの結果)'はより良いデザインです –
また、 'convertables'をコンストラクタに渡すことが最良の方法であるとは確信していません。それはおそらく方法であるべきです。そして、他の操作(「実際には店舗 //持ち、より多くの機能があります」)は、「EntityConverter」によるhttps://en.wikipedia.org/wiki/Single_responsibility_principleの違反の可能性を示唆しています。コンバータは変換する必要があります - その名前が示すものです。 –