1

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;
}
4
  • Can you post a little more code? It seems like you are writing a serializer. If I knew a little more of the code, I could help you with this. Commented Dec 14, 2012 at 17:19
  • Side note: you've tried both built in JSON serialization and third party (like JSON.Net) and for some reason nothing works and you have to build you own, right? Commented Dec 14, 2012 at 17:22
  • Im not writing a serializer, im just making a GUI to generate the json (with JSON.net). I am trying to write it in a way that if we add new types to the "Data" project, we dont have to modify this program. Ill post some more code though. Commented Dec 14, 2012 at 18:45
  • Solved the problem in another question, see here: stackoverflow.com/questions/13917915/… Commented Dec 17, 2012 at 17:06

2 Answers 2

2

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

list.Cast<object>().ToArray();
Sign up to request clarification or add additional context in comments.

1 Comment

nope, all of the elements are already what I want them to be, the array type is still object[] which I cannot cast to mytype[]
0

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

1 Comment

This wont work. "ob" has to be an object array with type= object{MyType[]} when you pass it to InvokeMember or it absolutely will not work. In your example 1: "ob"'s type is object{object[]} example 2 it is object{List<object>}. To clarify, "ob" has to match the type of the Property you are invoking (if it is a property that you are invoking). IT also has to be an object[] not just an object

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.