• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 694
  • Last Modified:

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);
    }
}
0
FrancineTaylor
Asked:
FrancineTaylor
  • 4
  • 2
1 Solution
 
lenordisteCommented:
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now