在 ASP.NET 中使用属性和反射实现对比表。






4.23/5 (13投票s)
2003 年 10 月 13 日
3分钟阅读

73429

838
一个通用的方案,用于在 ASP.NET 中使用属性和反射比较一个类的多个实例的属性。
引言
大多数在线商店都支持一项功能,用户可以选择来自不同供应商的多个产品并进行比较。例如,在 http://www.sonystyle.com/ 中,用户可以选择数码相机中提供的不同型号,并在它们之间进行比较。此比较表基本上列出了用户将在数码相机中寻找的关键功能,并显示每个型号的功能。下面显示了此类比较表的示例
最近,我正在阅读我们的一位业务人员提出的要求,我意识到它与这些网站上显示的比较表类似。由于开发平台是 .NET,我决定利用 .NET 的功能。
问题定义
- 用户必须能够选择不同的对象并比较它们的属性。比较的对象始终是同一类型。
- 必须能够在其他现有和新的 Web 应用程序中重用此实现。
目标
- 通用方案,以便可以在多个项目中重用它。
- 方案应该简单、易于理解、可扩展和可定制。
使用的功能
经过一段时间的思考,我决定使用 .NET 的以下功能来实现目标。
- 属性
- Reflection(反射)
- Web 自定义控件 (ASP.NET)
方案如何运作
我定义了一个名为 CompareAttribute
的属性,它有两个属性,分别是 DisplayTitle
和 DisplayOrder
。任何属性需要在比较表中列出的类都应该用这个属性来装饰。
[AttributeUsage(AttributeTargets.Property)]
public class CompareAttribute : System.Attribute
{
private int __displayOrder = 0;
private string __displayName = string.Empty;
public CompareAttribute(int DisplayOrder, string DisplayName)
{
__displayOrder = DisplayOrder;
__displayName = (DisplayName == null) ? "<undefined>" :
DisplayName.Trim();
}
public int DisplayOrder
{
get
{
return __displayOrder;
}
}
public string DisplayName
{
get
{
return __displayName;
}
}
}
我定义了一个名为 DiffTable
的 Web 自定义控件,它包含呈现比较表的逻辑。这个自定义控件公开了一个名为 ObjectsToCompare
的属性,类型为 ArrayList
。如果您提供一个包含您要比较的对象列表的 arraylist,那么控件将执行必要的魔法并显示 Comparison
表。
为了说明这个方案,我定义了一个名为 Camera
的示例类。这个 Camera 类有五个属性 - Name
、Model
、Price
、Warranty
和 HasCarlZeiss
。我用 compare 属性装饰了每个属性。
用 compare 属性装饰的类属性看起来像
[Compare(5, "Warranty Info")]
public string Warranty
{
get
{
return __warranty;
}
set
{
__warranty = (value == null) ? string.Empty : value.Trim();
}
}
自定义控件使用反射来识别正在比较的对象的类型。 此外,它还确保用户至少分配了 2 个对象实例以进行比较。
private SortedList FetchComparableProperties(Type type)
{
SortedList prps = new SortedList(32);
CompareAttribute cmp = null;
foreach(PropertyInfo prpInfo in type.GetProperties())
{
cmp = (CompareAttribute)Attribute.GetCustomAttribute(
prpInfo, typeof(CompareAttribute));
if(cmp != null)
{
if(prps.ContainsKey(cmp.DisplayOrder))
throw new Exception(string.Format(
"A property with the same display" +
" order of {0} already exists.",
cmp.DisplayOrder));
prps.Add(cmp.DisplayOrder, prpInfo);
}
}
return prps;
}
自定义控件中的上述代码显示了用于识别标记有 CompareAttribute
的属性,并根据 compare 属性装饰中指定的 Display
Order 值按排序顺序排列属性的逻辑。
下载包含一个示例 Web 应用程序,该应用程序显示由此方案生成的比较表。 下载还包含 Web 自定义控件的源代码。 我已在 Web 自定义控件中的每个函数中添加了足够的文档,以便于理解。
亮点
- 由于此方案基于元数据,因此即使将来向解决方案添加新类,只需使用 compare 属性装饰属性即可启用此类的实例进行比较,而无需更改现有代码。
- 由于核心逻辑是作为 Web 自定义控件实现的,因此它是独立的且易于分发。 此控件可以在多个 Web 应用程序中重用。
改进
- 可以扩展此方案以支持分组比较 - 相关属性将分组在标题下(类似于 http://www.dealtime.com/ 中的功能)。
- 通过添加 ImageUrl 等属性,可以在比较表中显示每个被比较对象的图像。
- 以及更多...
结论
要在经典的 ASP 中实现类似的功能,这将非常繁琐且耗时。 在 .NET 框架的帮助下,事情变得非常容易,并且可以在短时间内实现。 我认为每个人都会意识到 .NET 让我们的生活变得更加轻松。