7

I have written this code in visual studio 2013 utilizing .net v4.5. The problem I am having is that I am now having to drop down to .net v3.5 and the dynamic keyword is throwing an error as missing an assembly reference. Is there an equivalent type to 'dynamic' in .net v3.5 or a way for me to achieve the same results as below?

I thought I may have found my answer here, but var is throwing errors when I add the .Attributes or .Text property modifications.

private void CreateControl<T>(string objText,
                              Panel pnl,
                              string HTMLTag = "<td>",
                              string applicantID = "",
                              EventHandler hndl = null)
{
    pnl.Controls.Add(new LiteralControl(HTMLTag));
    dynamic obj = Activator.CreateInstance(typeof(T));
    obj.Text = objText;

    if (applicantID != string.Empty)
    {
        obj.Attributes.Add("ApplicantID", applicantID);
    }
    if (hndl != null)
    {
        obj.Click += new EventHandler(hndl);
    }

    pnl.Controls.Add(obj);
    pnl.Controls.Add(new LiteralControl(HTMLTag.Insert(1, "/")));
}
5
  • 3
    No. in 3.5 there is no Dynamic keyword. And you can use object. Honestly, unless you use dynamic in conjunction with interop, something is wrong with your design` Commented Feb 17, 2014 at 21:32
  • the Object keyword causes the same issues. Tells me there is no definition for 'Attritbutes'|'Text'. Further elaboration might be helpful? Commented Feb 17, 2014 at 21:34
  • 1
    Is there a reason for the object it instantiates to be dynamic? If you were to apply a type constraint to some Control base class/interface, it seems like it should work. Commented Feb 17, 2014 at 21:34
  • @48klocs It might be a misuse of the dynamic keyword, but I have no clue which type <T> is coming through the generic class. It could be anything from an asp:textbox to a tinymce:textarea. Commented Feb 17, 2014 at 21:36
  • What you should of done is derive your controls from same interface and use that instead of T Commented Feb 17, 2014 at 22:02

4 Answers 4

5

Instead of trying to hack this together in some bound to fail way and since there isn't a 'dynamic' control in .net v3.5, I have instead decided to just completely forgo this method and wrote some overloads instead. This way seems safer at this point; works the same, just a bit more code...

    #region CreateControl() Overloads
            /// <summary>
            /// Creates a LinkButton control.
            /// </summary>
            /// <param name="objText">.Text property of this LinkButton control.</param>
            /// <param name="pnl">Panel this control will be attached to.</param>
            /// <param name="hndl">Event handler attached to this LinkButton control.</param>
            /// <param name="HTMLTag">Opening tag used to contain this control.</param>
            private void CreateControl(string objText,
                                       Panel pnl,
                                       EventHandler hndl,
                                       string HTMLTag)
            {
                pnl.Controls.Add(new LiteralControl(HTMLTag));
                LinkButton obj = new LinkButton();
                obj.Text = objText;
                obj.Click += new EventHandler(hndl);

                pnl.Controls.Add(obj);
                pnl.Controls.Add(new LiteralControl(HTMLTag.Insert(1, "/")));
            }
            /// <summary>
            /// Creates a Label control.
            /// </summary>
            /// <param name="objText">.Text property of this Label control.</param>
            /// <param name="pnl">Panel this control will be attached to.</param>
            /// <param name="HTMLTag">Opening tag used to contain this control.</param>
            private void CreateControl(string objText,
                                       Panel pnl,
                                       string HTMLTag)
            {
                pnl.Controls.Add(new LiteralControl(HTMLTag));
                Label obj = new Label();
                obj.Text = objText;

                pnl.Controls.Add(obj);
                pnl.Controls.Add(new LiteralControl(HTMLTag.Insert(1, "/")));
            }
            /// <summary>
            /// Creates the specified literal control.
            /// </summary>
            /// <param name="ControlText">HTML text containing instructions for creating the desired literal control.</param>
            /// <param name="pnl">Panel this literal control will be attached to.</param>
            private void CreateControl(string ControlText, 
                                       Panel pnl)
            {
                pnl.Controls.Add(new LiteralControl(ControlText));
            }
        #endregion
Sign up to request clarification or add additional context in comments.

2 Comments

Glad you sorted it out; your solution makes a lot of sense compared to "hacking it together" +1
Just use an ExpandoObject in .Net 3.5 in place of dynamic. Just reference System.Dynamic
2

Is there an equivalent type to 'dynamic' in .net v3.5

No. dynamic requires .NET 4.0.

or a way for me to achieve the same results as below?

You could use reflection instead of dynamic to create the control and add your event handlers.

However, since this appears to be one of a few custom controls you're creating (given the attributes, etc), you may be able to constrain to an interface or base class, which would allow you to create the items and use those shared properties directly.

2 Comments

Could you point to a reference of the use of reflection to complete this function? I googled it and don't quite follow.
@Volearix You'd have to get the PropertyInfo, and then use SetValue to set the text, etc- see msdn.microsoft.com/en-us/library/f7ykdhsy.aspx
0

Based on your code, it looks like you're writing a generic method to pass in some unknown controls and attach them to a panel.

It also looks like you're dealing with different types of controls; i.e., not all WebControls have Text, and Attributes, AND Click properties;

This is a bit hacky but works in 3.5 - you can just use casting of the various underlying types or interfaces to access the needed properties, something like this:

private void CreateControl<T>(string objText, Panel pnl, string HTMLTag, 
    string applicantID, EventHandler hndl)
        where T : Control, new()
{
    pnl.Controls.Add(new LiteralControl(HTMLTag));
    T obj = new T();

    if (obj is ITextControl) (obj as ITextControl).Text = objText;

    if (applicantID != string.Empty && obj is WebControl)
        (obj as WebControl).Attributes.Add("ApplicantID", applicantID);


    if (obj is IButtonControl)
    {
        (obj as IButtonControl).Text = objText;
        if (hndl != null)
        {
            (obj as IButtonControl).Click += new EventHandler(hndl);
        }
    }

    pnl.Controls.Add(obj as Control);
    pnl.Controls.Add(new LiteralControl(HTMLTag.Insert(1, "/")));
}

Test code:

protected void Page_Load(object sender, EventArgs e)
{
    var panel = new Panel();

    CreateControl<Button>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));
    CreateControl<Label>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));
    CreateControl<Panel>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));
    CreateControl<Literal>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));

    //This won't compile because object doesn't fit <control> constraint
    //CreateControl<object>("test", panel, "<td>", "123", (s, args) => Console.WriteLine("hello!"));
}

To be honest I'm not 100% sure I like this approach. I might use some more specific methods and possibly method overloading to get more specific with different types of control creation, but this may help point you in the right direction.

Note that optional parameters are also not yet "invented" in C# 3.0 which shipped with .net 3.5, so you have to actually pass in all of the values.

9 Comments

No way. Then, why not factory?
@T.S.: Factory is another option sure. I made the disclaimer in the answer that I wouldn't do it this way; however, this code most closely resembles what OP is trying to do and also compiles in .net 3.5. Completely refactoring/rearchitecting OP's code is beyond the scope of SO, is it not? (Though I admit where it's glaringly obvious I will do so when I provide some answers). Here it would be like writing a whole new bunch of code.
You are double casting all the time, do one as cast and check for null! Just because it fits on a single line, doesn't mean it's faster in any way..
The way to do this is to wrap all controls to a common interface and instead of CreateControl<T> (...) have CreateControl (IMySystemControl c, ...) . I am telling you, people get the keywords and do whatever they like with it :o)
@T:S.: Then he has to subclass all of the controls - these are native asp.net controls he's working with. Then, the subclasses would implement a common interface that contains properties not all of the subclasses ever use, such as for example a Click event on a Literal control. I am not a fan of that idea, personally, either.
|
-3

dynamic keyword is available on .net 4.x and is a simple way to store any kind of value, it just resolve his type in runtime. It has been useful to me working with JSON strings.

string jsonValue = "{name:'Pedro',lastName:'Mora'}";
dynamic Variable = new JavascriptSerializer().Deserialize<dynamic>(jsonValue);
return Variable.name;
//It will return "Pedro"

Thing is that you have to be sure that the value won't be null and the properties or attributes or methods or something refered to the object exists and it takes it's values on runtime.

3 Comments

This in no way answers the question of how to replicate this behavior pre .NET 4.0, which is what the question is asking.
@pedritin This isn't my question, please re-read. I'm needing an alternative to dynamic, not how it works.
I'm sorry. I just said what I use it and explain tha it take his type in runtime. I think you should convert it to object, evaluate if is not null and then get its base type. the load the assembly of the type, of something like that.

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.