使用generics创建HtmlHelper扩展方法

我对创建generics方法并不熟悉,所以我想我会把这个问题提交给社区,看看会有什么回来。 它甚至可能不是generics的有效使用!

我想创建一个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(this HtmlHelper h, object myType, TagBuilder tag) { // cast myType to T //(ie MyType) // use reflection to get the properties in MyType // get values corresponding to the properties // build up tag's attribute/value pairs with properties. } 

理想情况下我可以打电话:

   <%= Html.GetTag(myType, tag) %> 

并生成的HTML将是

 

后来,我可以打电话

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

要得到

 

它甚至可能吗? 或者我是以完全错误的方式看待这个? 有人愿意让我接受更好的方法吗?

谢谢

戴夫

对于你想要做的事情,我认为使用generics的主要好处是利用类型推断。 如果您声明方法如下:

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

调用它时不必指定type参数,因为它将从用法中推断出来(即编译器会看到第二个参数的类型是MyType ,因此它会猜测T == MyType)。

但无论如何,你真的不需要指定类型:方法可以在对象上调用GetType ,并使用与使用typeof(T)相同的结果类型,因此generics在这里不太有用。

但是,无论如何,我看到一个使用它们的原因:如果你有一个inheritance自MyType MySubType类型的对象,你可能只想渲染MyType中定义的属性:在这种情况下,你只需要指定MyType作为类型参数,覆盖类型推断。

这是一个可能的实现:

 public static string GetTag(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(); } 

我认为仿制药并不完全是你在这里寻找的东西。

相反,您可能想要采用两种不同方法中的一种

  1. 让所有类都来自一个普通的类,它有一个名为“Render”的虚拟方法或类似的东西。 这样你就可以调用类的render方法。

  2. 使所有类实现一个具有Render方法的接口。

那你要打电话:

虽然每个类都必须实现它自己的Render方法,但你要避免reflection,2。在类的基础上完全控制输出。