繁体   English   中英

在.Net 3.5中使用动态关键字

[英]Use of Dynamic Keyword in .Net 3.5

我已经使用.net v4.5在visual studio 2013中编写了这段代码。 我遇到的问题是我现在不得不下载到.net v3.5并且动态关键字抛出错误,因为缺少程序集引用。 在.net v3.5中是否有与“动态”相同的类型,或者我可以通过以下方式获得相同的结果?

我以为我可能在这里找到了答案,但是当我添加.Attributes或.Text属性修改时var会抛出错误。

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, "/")));
}

而不是试图以某种方式一起破解这种方式,因为在.net v3.5中没有“动态”控制,我决定完全放弃这种方法,而是写了一些重载。 这种方式在这一点似乎更安全; 工作原理相同,只需要更多代码......

    #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

在.net v3.5中是否存在与“dynamic”等效的类型

编号dynamic需要.NET 4.0。

或者我可以通过以下方式获得相同的结果?

您可以使用反射而不是dynamic来创建控件并添加事件处理程序。

但是,由于这似乎是您正在创建的一些自定义控件之一(给定属性等),您可能能够约束到接口或基类,这将允许您创建项目并使用这些项目属性直接。

根据您的代码,看起来您正在编写一个通用方法来传递一些未知控件并将它们附加到面板。

看起来你正在处理不同类型的控件; 即,并非所有WebControl都具有Text,Attributes和AND属性;

这有点hacky但在3.5中工作 - 您可以使用各种底层类型或接口的转换来访问所需的属性,如下所示:

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, "/")));
}

测试代码:

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

说实话,我不是100%肯定我喜欢这种方法。 我可能会使用一些更具体的方法和可能的方法重载来更具体地使用不同类型的控件创建,但这可能有助于指向正确的方向。

请注意, optional parameters还没有在.net 3.5附带的C#3.0中“发明”,因此您必须实际传入所有值。

动态关键字在.net 4.x上可用,是存储任何类型值的简单方法,它只是在运行时解析它的类型。 使用JSON字符串对我很有用。

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

事情是你必须确保该值不为null并且属性或属性或方法或对象存在的东西存在,并且它在运行时获取它的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM