C# 在.NET3.5中使用动态关键字

C# 在.NET3.5中使用动态关键字,c#,object,dynamic,controls,C#,Object,Dynamic,Controls,我已经在visual studio 2013中使用.net v4.5编写了这段代码。我现在遇到的问题是,我现在不得不下拉到.NETV3.5,而dynamic关键字由于缺少程序集引用而抛出错误。在.NETV3.5中是否有与“dynamic”等效的类型,或者是否有一种方法可以让我获得与下面相同的结果 我想我可能已经找到了答案,但是当我添加.Attributes或.Text属性修改时,var抛出了错误 private void CreateControl<T>(string objText

我已经在visual studio 2013中使用.net v4.5编写了这段代码。我现在遇到的问题是,我现在不得不下拉到.NETV3.5,而dynamic关键字由于缺少程序集引用而抛出错误。在.NETV3.5中是否有与“dynamic”等效的类型,或者是否有一种方法可以让我获得与下面相同的结果

我想我可能已经找到了答案,但是当我添加.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, "/")));
}
private void CreateControl(字符串objText,
专家组pnl,
字符串HTMLTag=“”,
字符串applicationId=“”,
EventHandler(hndl=null)
{
添加(新的LiteralControl(HTMLTag));
dynamic obj=Activator.CreateInstance(typeof(T));
obj.Text=objText;
if(applicationId!=string.Empty)
{
添加(“应用程序标识”,应用程序标识);
}
如果(hndl!=null)
{
obj.Click+=neweventhandler(hndl);
}
pnl.Controls.Add(obj);
pnl.Controls.Add(新的LiteralControl(HTMLTag.Insert(1“/”)));
}
在.net v3.5中是否存在与“dynamic”等效的类型

否。
动态
需要.NET 4.0

或者是一种让我达到以下相同结果的方法

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


但是,由于这似乎是您正在创建的几个自定义控件之一(给定属性等),因此您可以约束到接口或基类,从而允许您创建项并直接使用这些共享属性。

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

string jsonValue = "{name:'Pedro',lastName:'Mora'}";
dynamic Variable = new JavascriptSerializer().Deserialize<dynamic>(jsonValue);
return Variable.name;
//It will return "Pedro"
string jsonValue=“{name:'Pedro',lastName:'Mora'}”;
动态变量=新的JavascriptSerializer()。反序列化(jsonValue);
返回变量.name;
//它将返回“Pedro”

问题是,您必须确保值不会为null,并且对象的属性、属性、方法或引用的对象存在,并且它在运行时接受其值。

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

看起来你也在处理不同类型的控件;i、 例如,并非所有的网络控件都有文本、属性和单击属性

这有点不成熟,但适用于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, "/")));
}
private void CreateControl(字符串objText、面板pnl、字符串HTMLTag、,
字符串应用程序ID,事件处理程序hndl)
其中T:Control,new()
{
添加(新的LiteralControl(HTMLTag));
T obj=新的T();
if(obj为ITextControl)(obj为ITextControl)。Text=objText;
if(applicationId!=string.Empty&&obj为网络控制)
(obj作为网络控制).Attributes.Add(“applicationId”,applicationId);
if(obj为IButtonControl)
{
(obj作为IButtonControl)。Text=objText;
如果(hndl!=null)
{
(对象为IButtonControl)。单击+=新建事件处理程序(hndl);
}
}
pnl.Controls.Add(对象作为控件);
pnl.Controls.Add(新的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!"));
}
受保护的无效页面加载(对象发送方,事件参数e)
{
变量面板=新面板();
CreateControl(“test”,panel,”,“123”,(s,args)=>Console.WriteLine(“hello!”);
CreateControl(“test”,panel,”,“123”,(s,args)=>Console.WriteLine(“hello!”);
CreateControl(“test”,panel,”,“123”,(s,args)=>Console.WriteLine(“hello!”);
CreateControl(“test”,panel,”,“123”,(s,args)=>Console.WriteLine(“hello!”);
//因为对象不符合约束,所以无法编译
//CreateControl(“test”,panel,”,“123”,(s,args)=>Console.WriteLine(“hello!”);
}
老实说,我不是100%确定我喜欢这种方法。我可能会使用一些更具体的方法,也可能使用方法重载来更具体地创建不同类型的控件,但这可能有助于为您指明正确的方向


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

而不是试图以某种必然失败的方式将其组合在一起,因为.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
#region CreateControl()重载
/// 
///创建链接按钮控件。
/// 
///.此LinkButton控件的文本属性。
///此控件将连接到的面板。
///附加到此LinkButton控件的事件处理程序。
///用于包含此控件的打开标记。
私有void CreateControl(字符串objText,
专家组pnl,
事件处理程序hndl,
字符串(HTMLTag)
{
添加(新的LiteralControl(HTMLTag));
LinkButton obj=新的LinkButton();
obj.Text=objText;
obj.Click+=neweventhandler(hndl);
pnl.Controls.Add(obj);
pnl.Controls.Add(新的LiteralControl(HTMLTag.Insert(1“/”)));
}
/// 
///创建标签控件。
/// 
///.此标签控件的文本属性。
///此控件将连接到的面板。
///用于包含此控件的打开标记。