リフレクションを使用して、DTO (xSearchQuery) から 1 つのクラス (xSearchObject) にマップ (プロパティを設定) しています。達成しようとしていることを簡単に確認できるように、コードを削減しようとしました。変えることはできませんがSearchField
、変えることはできますDTOSearchField
。
- ソース クラスには、タイプ のn 個のプロパティがあり
DTOSearchField<T>
ます。 - 宛先クラスには、タイプ のn 個のプロパティがあり
SearchField<T>
ます。 - ソースと宛先には、同じ名前の同じ数のプロパティがあります。
ソース クラス プロパティ タイプ
public class DTOSearchField<T> : IDTOSearchField
{
public T EqualTo;
}
宛先クラス プロパティ タイプ:
public class SearchField<T> : ISearchField
{
public void WhereEquals(T value)
{
_clauses.Add(_name + " = " + Converter.ConvertValueToSql(value));
}
// etc
}
マッピング: ( Lightweight Object to Object Mapper に基づく) ジェネリックの代わりに、DTOSearchField<T>
たとえばなどのクラスを持っていて、それらにキャストすると、マッピングを非常にうまく行うことができます。したがって、ソース プロパティごとに次のようになります。StringDTOSearchField
IntDTOSearchField
if (sourceVal.GetType().IsAssignableFrom(typeof(StringDTOSearchField)))
{
var destinationProperty = destinationPropertyAccessor.GetPropertyValue(destination, propertyMatch.DestinationProperty.Name) as SearchField<string>;
var sourceStringField = sourceVal as StringSearchField;
if (sourceStringField != null)
{
if (!string.IsNullOrEmpty(sourceStringField.EqualTo)) destinationProperty.WhereEquals(sourceStringField.EqualTo);
}
}
else if (sourceVal.GetType().IsAssignableFrom(typeof(IntDTOSearchField)))
{
// Etc
}
または、ジェネリックDTOSearchField<T>
を保持して、以下に基づいて If-Then-elses を実行することもできます。
Type t = sourceVal.GetType().GetGenericArguments()[0];
適切な型にキャストするには、
しかし、私は次のようなことができるはずだと感じています:
Type t = sourceVal.GetType().GetGenericArguments()[0];
var destinationProperty = destinationPropertyAccessor.GetPropertyValue(destination, propertyMatch.DestinationProperty.Name) as SearchField<t>;
destinationProperty.WhereEquals(sourceVal.EqualTo.Value);
sourceVal
is aDTOSearchField<T>
とdestinationProperty
is aであり、どちらも T 型のプロパティを持っているためSearchField<T>
、実行時まで T が何であるかを知らなくても問題ないように感じます。
T は実行時までわからないため、キャストが機能しないことを理解しています。可能なすべてのタイプのIf-Then-Else以外に、私が望むものを達成する方法はありますか? 私がそうしなければならない場合、ジェネリックを使用する利点を無効にしているようです。
ありがとう、