【发布时间】:2013-12-24 15:01:35
【问题描述】:
假设我们有一个名为“Tag”的类。
public class Tag
{
public string Name { get; private set; }
public string Description { get; private set; }
public Type Type { get; private set; }
public Tag(string name, string description, Type type)
{
this.Name = name;
this.Description = description;
this.Type = type;
}
}
标签实例的示例如下:
Tag weightTag = new Tag("Weight", "Weight of item in kg", typeof(double))
接下来假设我有另一个类,它具有这些标签的集合,其中一个与该对象相关的值映射到集合中的每个单独的标签。
public class Item
{
public string Id { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public Dictionary<Tag, object> Tags { get; private set; }
public Item(string name, string description)
{
this.Name = name;
this.Description = description;
this.Tags = new Dictionary<Tag, object>();
}
public void AddTag(Tag tag, object value)
{
Tags.Add(tag, value);
}
}
我喜欢这种方法,因为你可以从某个地方获取一些预定义的标签,然后分配一个值。
Tag buildDateTag = TagProvider.GetByName("BuildDate");
Tag weightTag = TagProvider.GetByName("Weight");
item.AddTag(buildDateTag, new DateTime(2013,12,06);
item.AddTag(weightTag, 10.5);
这种方法的缺点是会有很多装箱/拆箱。例如,如果我有一个 Item 集合,并且我想将与重量相对应的标签的所有值相加,我必须执行以下操作:
double totalWeight = 0d;
foreach (var item in items)
{
if (Tags.ContainsKey(weightTag))
{
totalWeight += (double)Tags[weightTag];
}
}
在这种情况下,我碰巧知道我要加倍,所以唯一的性能损失是拆箱。但是在某些情况下,我需要从 Tag 对象的 Type 成员中获取对象的类型,以便确定值对象的类型。
我的问题是你认为有没有更好的方法来构建它,以便摆脱依赖使用对象和每次我想使用值时拆箱的需要?
虽然这应该是一个不同的问题,但在这种用法中,Tag 应该是一个结构而不是一个类?
【问题讨论】:
-
似乎您直接违背了 .NET 提供的主要好处:强类型对象。为什么需要在集合中支持这些随机类型而不是强类型?
-
@DavidHaney 我同意您确实失去了强类型对象的主要好处。这闻起来更像 Python 而不是 C#。您会如何建议修改此特定设计以使其具有更强的类型?
-
您能否更好地解释一下您在此设计中的目标是什么?如果我知道我可以就如何处理它提出更好的意见。
-
@DavidHaney 基本上这种设计是一种 EAV 方法。为了概括地描述架构,我们希望能够通过例如 xml 文件来定义对象在运行时具有的属性。这种方法使我们能够做到这一点。所以假设我们有一个产品对象作为基类。如果我们想创建具有新属性的新产品,我们要么在编译时创建具有相关成员的子类,要么在运行时使用此方法。
-
但这在运行时会给你带来什么好处,因为你需要业务逻辑,我认为目前是编译时才能对这些对象采取行动?
标签: c# .net c#-4.0 dictionary