How can I translate a custom type to a generic <T> method?

I have a class with a number of parallel methods, one for system objects and another for generic types.  For example:

// use this for arrays, strings, datatables, etc
public void DoSomething(object somedata) {
}
// only use for an array of a custom type
public void DoSomething<T>(T[] data) {
}

I would like to be able to pass in to a method an object which may or may not be an array of custom objects, and have my method call the appropriate version of the DoSomething method.

public void MyMethod(object data) {
    Type type = data.GetType();
    if (IsCustomType(type)) {
        // How would I call the generic form of the method based on the data?
        DoSomething<T>(data);
    }
    else {
        DoSomething(data);
    }
}
LVL 1
FrancineTaylorAsked:
Who is Participating?
 
lenordisteConnect With a Mentor Commented:
here is a post on someone who had the exact same problem as you. It involves using reflection and the MakeGenericMethod() function of Type:
http://stackoverflow.com/questions/325156/calling-generic-method-with-a-type-argument-known-only-at-execution-time

on a side note I think having a generic method is good in the sense that it helps infer the type at compilation time... so in your scenario I don't really see the use of the generic method: class inheritance would be in my opinion a better approach since you are only dealing with custom types in your example.
0
 
FrancineTaylorAuthor Commented:
It works almost perfectly.  The main problem is in this line:

MethodInfo method = typeof(cFormDisplay).GetMethod("DoSomething");

It returns the error "Ambiguous match found".  If I comment out the non-generic verion of the method it works just fine.  What that means is that I can't give my generics and non-generic methods the same name.  A minor inconvenience.
0
 
FrancineTaylorAuthor Commented:
Thanks for your help.
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

 
lenordisteCommented:
Type.GetMethod also takes in other arguments that can help you avoid this issue. You can specify an array of types to retrieve the method with corresponding arguments.

Take a look at this for more info: http://msdn.microsoft.com/en-us/library/6hy0h0z1.aspx
0
 
FrancineTaylorAuthor Commented:
I can see that I can pass BindingFlag and type array parameters, but I can't figure out how to apply them in this situation.  Here's my code:

public partial class Form1 : Form {
     private void button1_Click(object sender, EventArgs e) {
                MyTestClass test = new MyTestClass();
                cEquipment[] eqs = cTestData.CreateEquipment().ToArray();
                object equip = (object)eqs;
                MethodInfo method = typeof(cFormDisplay).GetMethod("DoSomething");
                MethodInfo genericMethod = method.MakeGenericMethod(typeof(cEquipment));
                genericMethod.Invoke(test, new object[] { (cEquipment[])equip });
     }
}public class MyTestClass {
    public MyTestClass() {
    }
    // use this for arrays, strings, datatables, etc
    public void DoSomething(object data) {
        MessageBox.Show("Calling non-generic");
    }
    // only use for an array of a custom type
    public void DoSomething<T>(T[] data) {
        MessageBox.Show("Calling generic");
    }
}

The GetMethod line throws "Ambiguous match found".  Can you help me figure out how to modify it so that it doesn't throw an error, and it returns the generic method?
0
 
FrancineTaylorAuthor Commented:
Sorry, that example had a bug and wasn't completely paste-and-run.  Here it is again.  I included all the code needed to run, with a modification that I tried.  I sent GetMethod the type of parameter that I was sending in, and it returned the wrong method.  How can I specifically get it to return the generic method?

public class cJunk1 {
    public static void TestMe() {
        MyTestClass test = new MyTestClass();
        cStudent[] eqs = new cStudent[] { new cStudent() };
        object equip = (object)eqs;
        //MethodInfo method = typeof(MyTestClass).GetMethod("DoSomething");
        Type[] tt = new Type[] { typeof(cStudent[]) };
        MethodInfo method = typeof(MyTestClass).GetMethod("DoSomething", tt);
        MethodInfo genericMethod = method.MakeGenericMethod(typeof(cStudent[]));
        genericMethod.Invoke(test, new object[] { (cStudent[])equip });
    }
}
public class MyTestClass {
    public MyTestClass() {
    }
    // use this for arrays, strings, datatables, etc
    public void DoSomething(object data) {
        MessageBox.Show("Calling non-generic");
    }
    // only use for an array of a custom type
    public void DoSomething<T>(T[] data) {
        MessageBox.Show("Calling generic");
    }
}
public class cStudent {
    public string name = null;
    public cStudent() {
    }
}
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.