2010-03-09 60 views
1

我并不是很熟悉创建泛型方法,所以我想我会把这个问题提交给社区&看看会发生什么。它甚至可能不是泛型的有效使用!使用泛型创建HtmlHelper扩展方法

我想创建一个HtmlHelper扩展方法,我可以指定该方法是某种类型。我将该类型的实例和TagBuilder对象的实例传递给方法。然后,我将该标记的class属性指定为传入的对象的类型,并将所有对象的属性序列化为标记的属性。

编辑... 这样做的好处是,我可以很容易地然后我序列化的HTML元素在成JavaScript的jQuerying对象服务器&模型绑定,以及为一类指定样式的能力 ...结束编辑

此代码示例可能会阐明。

我有一种类型是这样的:

public class MyType 
{ 
    public int Prop1 { get; set; } 
    public int Prop2 { get; set; } 

    public MyType(int val1, int val2) 
    { 
     this.Prop1 = val1; 
     this.Prop2 = val2; 
    } 
} 

我在想什么是产生一个辅助方法,可能与类似这样的签名:

public static string GetTag<T>(this HtmlHelper h, object myType, TagBuilder tag) 
{ 
    // cast myType to T //(i.e. MyType) 
    // use reflection to get the properties in MyType 
    // get values corresponding to the properties 
    // build up tag's attribute/value pairs with properties. 
} 

理想的情况下,我可以再调用:

<% var myType = new MyType(123, 234); %> 
<% var tag = new TagBuilder("div"); %> 
<%= Html.GetTag<MyType>(myType, tag) %> 

和产生的HTML将是

<div class="MyType" prop1="123" prop2="234" /> 

,后来,我可以叫

<%= Html.GetTag<MyOtherType>(myOtherType, tag) %> 

得到

<div class="MyOtherType" prop1="123" prop2="234" /> 

它甚至有可能?或者我看着这完全错误的方式?任何人都在意让我更好的方法吗?

感谢

戴夫

+0

这是可能的,但除非你传递的类型有有效的HTML属性,这会产生无效的HTML。你确定你要这么做吗?你能详细说明这个的目的吗? – Omar

+0

@Baddie,我编辑说:“这样做的好处是,我可以轻松地将我的Html元素序列化为javascript对象,以便jQuerying到服务器和模型绑定,以及为类型指定样式的功能。我知道这是无效的Html,但是在XHTML文档的上下文中(即它是XML的一个子集,因此是可扩展的),使用自定义属性就可以了吗? – DaveDev

回答

3

对于你想要做的,我认为使用泛型的主要好处是利用类型推断。如果你申报你的方法如下:

public static string GetTag<T>(this HtmlHelper h, T myObj, TagBuilder tag) 

你不会有调用它时指定类型参数,因为它会从使用推断(即编译器会看到第二个参数的类型是MyType ,所以它会猜测T == MyType)。

但是不管怎样,你并不真的需要指定类型:该方法可以调用GetType的对象,并使用所产生的键入它会用typeof(T)以同样的方式,所以仿制药不那么有用这里。

但是,我看到一个理由来使用他们无论如何:如果你有MySubType类型,从MyType继承的对象,您可能希望只渲染在MyType定义的属性:在这种情况下,你只需要指定MyType为类型参数,覆盖类型推断。

这里是一个可能的实现:

public static string GetTag<T>(this HtmlHelper h, T myObj, TagBuilder tag) 
{ 
    Type t = typeof(T); 
    tag.Attributes.Add("class", t.Name); 
    foreach (PropertyInfo prop in t.GetProperties()) 
    { 
     object propValue = prop.GetValue(myObj, null); 
     string stringValue = propValue != null ? propValue.ToString() : String.Empty; 
     tag.Attributes.Add(prop.Name, stringValue); 
    } 
    return tag.ToString(); 
} 
2

我想仿制药是不是你正在寻找什么在这里。

相反,你可能要采取的两种不同的方法

  1. 让所有的类,从常见的一种,其具有所谓的“渲染”或类似的东西虚方法下降之一。这样你就可以调用类的render方法。

  2. 让你所有的类都实现具有Render方法的接口..

那你你只需拨打:

虽然每个类,那么必须实现它自己的渲染方法,你会1。避免反思,2.在课堂上完全控制输出。