动态转换为通用接口

时间:2012-09-03 10:13:16

标签: c# reflection

我有一个外部函数,其语法如下:

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

字段类型可以是一些原始类型,如 int double bool 等,也可以是这些类型的通用列表,例如的的IList&LT; int&gt;

问题是我必须准确传递一个 IList&lt; T&gt; 界面。如果我传递任何实现 IList&lt;的类型T> 接口函数抛出 InvalidOperationException 不支持的类型:System.Collections.Generic.List`1 [[System.Int32,mscorlib,Version = 4.0.0.0,Culture =中性,PublicKeyToken = b77a5c561934e089]]

例如:

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是 List&lt; T&gt; ,而不是 IList&lt; T&gt; ,当我将此值传递给外部函数时,我看到了异常。

显然,这是一个外部功能的错误。

我唯一的想法是将propertyValue转换为 IList&lt; T&gt; 但我在编译时不知道

所以,我需要动态投射。我有一个通用的列表接口类型,如变量

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

但我找不到如何将propertyValue转换为此类型的方法。我只能找到如何将对象转换为其他对象的示例(例如,使用 Activator.CreateInstance ),但我需要转换为接口。

请告诉我如何实现目标。

1 个答案:

答案 0 :(得分:4)

你可以包装外部函数:

public void SetWrapper<T>(Field field, List<T> list) {
    entity.Set(field, (IList<T>)list);
}