【问题标题】:Adding Tags and its respective value to an object将标签及其各自的值添加到对象
【发布时间】: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


【解决方案1】:

恕我直言,您可以使用一个接口,该接口具有您希望作为可以标记的对象的一部分的对象的一些通用属性。

在这种情况下,您可以接受任何实现您的接口的对象,因此,您将拥有简洁明了的代码

示例: 类 BuildDateTag : ITaggable { 内部标识; 字符串名称; 双倍重量; }

这样,您可以在Item 类中定义标签 public Dictionary<Tag, object> Tags { get; private set; } public Dictionary&lt;Tag,ITaggable&gt; Tags{get;set;}

考虑到这一点,并根据此建议发布查询和您的可行性

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-06
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 1970-01-01
    • 2017-05-31
    • 2018-09-04
    相关资源
    最近更新 更多