runtime casting of an object[] to a custom type ar

2019-07-31 02:41发布

I am making a tool for defining objects in WPF so they can be serialized into JSON for testing our REST service. It uses reflection to pull all the properties into the GUI, and generates a JSON based on the input. This works fantastically for everything except properties that are arrays of types that I defined. I am using the object.InvokeMember() method to accomplish this.

The problem is, you have to pass it an object array as the parameter. When its just one thing, its fine, but when its an array, it throws an exception because the object array isn't casted to the type the property is. This is hard to explain.

some code:

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; }
}

I am sure whoever reads this will be confused, so please ask questions.

More code, an example of modifying a type that is not an array. This part works fine:

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

Been trying something like this, but same deal, cant cast object[] to 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;
}

标签: c# reflection
2条回答
\"骚年 ilove
2楼-- · 2019-07-31 02:56

If you mean casting every single element of a collection to object you can use LINQ:

list.Cast<object>().ToArray();
查看更多
够拽才男人
3楼-- · 2019-07-31 02:59

Seems like your just doing a little too much casting... any [] is an object :)

Change the top code to this...

    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);
    }
}

Of it it really needs a List then just do this

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);
}
查看更多
登录 后发表回答