webnoob
webnoob

Reputation: 15934

Generic function issue - Cannot convert type 'System.Web.UI.Control' to 'T'

It seems I still don't "get" generics ... I want a general function to load a user control which inherently calls Page.LoadControl() but I am getting the error above when trying to make it work.

Here is a mock up of the code I use to load the control:

MyControl Ctrl = MyUtilClass.LoadControl(Page, "MyControl");

and then in MyUtilClass:

internal static T LoadControl<T>(Page P, string ControlName)
{
    return (T)P.LoadControl(String.Format("~/{0}{1}.ascx", WebGlobals.cControlDir, ControlName));
}

I am obviously doing something wrong but my understanding was the compiler would look at the type of var I am trying to assign the result of this function to and be able to cast the result as that type.

Upvotes: 0

Views: 1546

Answers (2)

Jodrell
Jodrell

Reputation: 35746

I think you need to constrain your generic function to Controls only, otherwise T is too generic for your purposes.

internal static T LoadControl<T>(Page P, string ControlName)
    where T : System.Web.UI.Control
{
    ...
}

EDIT

You could do this but I'm not sure its worth the extra complexity over the non generic approach in Daniel Hilgarth's answer.

internal static void LoadControl<T>(Page P, 
                                     string ControlName
                                     out T control)
    where T : System.Web.UI.Control
{
    control = (T)P.LoadControl(
                   String.Format("~/{0}{1}.ascx",
                                    WebGlobals.cControlDir, 
                                    ControlName));
}

calling like this

MyControl myControl;
LoadControl(page, "MyControl", myControl);

Upvotes: 2

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174457

You don't need generics for this. Simply make your method return Control:

internal static System.Web.UI.Control LoadControl(Page P, string ControlName)
{
    return P.LoadControl(String.Format("~/{0}{1}.ascx", WebGlobals.cControlDir,
                                                        ControlName));
}

If you put this method in a static class, you can make an extension method out of it, note the this before the first parameter of the method:

internal static System.Web.UI.Control LoadControl(this Page P, string ControlName)
{
    return P.LoadControl(String.Format("~/{0}{1}.ascx", WebGlobals.cControlDir, 
                                                        ControlName));
}

you can now call it like this:

var control = yourPage.LoadControl(controlName);

If you really want to have a MyControl instance, change the method to this:

internal static MyControl LoadControl(this Page P, string ControlName)
{
    return (MyControl)P.LoadControl(String.Format("~/{0}{1}.ascx", 
                                    WebGlobals.cControlDir, 
                                    ControlName));
}

Upvotes: 3

Related Questions