运行时将对象[]转换为自定义类型数组

时间:2012-12-14 17:07:39

标签: c# reflection

我正在制作一个用于在WPF中定义对象的工具,因此可以将它们序列化为JSON以测试我们的REST服务。它使用反射将所有属性拉入GUI,并根据输入生成JSON。除了我定义的类型数组的属性之外,这对于所有内容都非常有效。我正在使用object.InvokeMember()方法来完成此任务。

问题是,您必须将对象数组作为参数传递给它。当它只是一件事,它很好,但是当它是一个数组时,它抛出异常,因为对象数组没有被转换为属性的类型。这很难解释。

一些代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    object obj = new MyType();
    List<list<object>> list = new List<List<object>>();
    object[] ob = new object[] { list.ToArray() };
    obj.GetType().InvokeMember(
        "MyOtherTypes",
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
        Type.DefaultBinder,
        obj,
        ob);
    UpdateJson(obj);
}

public class MyType
{
    public MyOtherType[] MyOtherTypes { get; set; }
}

public class MyOtherType
{
    public int SomeProperty { get; set; }
}

我确信无论谁读到这些都会感到困惑,所以请提出问题。

更多代码,修改非数组类型的示例。这部分工作正常:

object[] ob = new object[] { obj };
obj.GetType().InvokeMember(
    "SomePropertyThatIsNotAnArray", 
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
    Type.DefaultBinder, 
    obj, 
    ob);
UpdateJson(obj);

尝试过这样的事情,但同样的交易,无法将对象[]转换为MyType []

MethodInfo castMethod = this.GetType().GetMethod("Cast").MakeGenericMethod(
    obj.GetType().MakeArrayType());
object castedObject = castMethod.Invoke(
    null, 
    new object[] { list[someIndex].ToArray() });
obj.GetType().InvokeMember(
    "SomePropertyThatIsNotAnArray",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
    Type.DefaultBinder, 
    obj, 
    castedObject);

public static T Cast<T>(object o)
{
    return (T)o;
}

2 个答案:

答案 0 :(得分:2)

如果您的意思是将集合的每个元素都转换为对象,则可以使用LINQ:

list.Cast<object>().ToArray();

答案 1 :(得分:0)

好像你只是做了太多的投射......任何[]都是object:)

将顶部代码更改为此...

    private void Button_Click(object sender, RoutedEventArgs e)
{
    object obj = new MyType();
    List<object> list = new List<object>();
    list.Add(obj);
    foreach (object o in obj in list){
    obj.GetType().InvokeMember(
        "MyOtherTypes",
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
        Type.DefaultBinder,
        obj,
        ob);
    UpdateJson(obj);
    }
}

它真的需要一个List然后就这样做

private void Button_Click(object sender, RoutedEventArgs e)
{
    object obj = new MyType();
    List<list<object>> list = new List<List<object>>();
    object ob = (object) list;
    obj.GetType().InvokeMember(
        "MyOtherTypes",
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
        Type.DefaultBinder,
        obj,
        ob);
    UpdateJson(obj);
}