2

次の構文を持つ外部関数があります。

public void Set<FieldType>(
    Field field,
FieldType value
) 

フィールド型は、 intdoubleboolなどのプリミティブ型の一部にすることができます。また、これらの型のジェネリック リストにすることもできます (例: IList< int >)。

問題は、 IList< T >インターフェイスを正確に渡さなければならないことです。IList< T >インターフェイスを実装する型を渡すと、関数はInvalidOperationExceptionをスローします 。 ]

例えば:

IList<int> list1 = new List<int>();
List<int> list2 = new List<int>();

Entity entity = new Entity();

//this works fine
entity.Set(field, list1);

//Here exception is throw
entity.Set(field, list2);

//works fine as well
entity.Set(field, list2 as IList<int>);

リフレクションを介して動的にリストを取得する問題

var property = entityType.GetProperty(field.FieldName);
dynamic propertyValue = property.GetValue(myObject, null);

したがって、propertyValue はIList< T >ではなくList< T >であり、この値を外部関数に渡すと例外が発生します。

明らかに外部関数のバグです。

私が持っている唯一のアイデアは、propertyValue をIList< T >にキャストすることです。しかし、私はコンパイル時に T を知りません

したがって、動的にキャストする必要があります。変数のような一般的なリスト インターフェイス型があります

var genericIListType = typeof (IList<>)
    .MakeGenericType(field.ValueType);

しかし、propertyValue をこの型にキャストする方法が見つかりません。オブジェクトを他のオブジェクトにキャストする方法の例しか見つけることができませんが (たとえば、Activator.CreateInstanceを使用)、インターフェイスにキャストする必要があります。

目標を達成するためのアドバイスをお願いします。

4

1 に答える 1

5

外部関数をラップできます:

public void SetWrapper<T>(Field field, List<T> list) {
    entity.Set(field, (IList<T>)list);
}
于 2012-09-03T10:21:24.577 に答える