2010-06-23 93 views
5

我有两个对象MetaItems和Items。C#泛型和集合

MetaItem是对象的模板,而Items包含实际值。例如,“部门”被视为元项目,“销售”,“英国地区”,“亚洲地区”被视为项目。

此外,我想维护这些元项目和项目上的亲子关系。对于同一

我有下面的代码 -

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace WpfApplication12 
{ 
    public interface IEntity 
    { 
     int Id { get; set; } 

     string Name { get; set; } 
    } 

    public interface IHierachy<T> 
    { 
     IHierachy<T> Parent { get; } 

     List<IHierachy<T>> ChildItems { get; } 

     List<IHierachy<T>> LinkedItems { get; } 

    } 

    public class Entity : IHierachy<IEntity>, IEntity 
    { 

     #region IObject Members 

     private int _id; 
     public int Id 
     { 
      get 
      { 
       return _id; 
      } 
      set 
      { 
       _id = value; 
      } 
     } 

     private string _name; 

     public string Name 
     { 
      get 
      { 
       return _name; 
      } 
      set 
      { 
       _name = value; 
      } 
     } 

     #endregion 

     #region IHierachy<IEntity> Members 

     public IHierachy<IEntity> _parent; 
     public IHierachy<IEntity> Parent 
     { 
      get 
      { 
       return _parent; 
      } 
     } 

     private List<IHierachy<IEntity>> _childItems; 

     public List<IHierachy<IEntity>> ChildItems 
     { 
      get 
      { 
       if (_childItems == null) 
       { 
        _childItems = new List<IHierachy<IEntity>>(); 
       } 
       return _childItems; 
      } 
     } 

     private List<IHierachy<IEntity>> _linkedItems; 

     public List<IHierachy<IEntity>> LinkedItems 
     { 
      get 
      { 
       if (_linkedItems == null) 
       { 
        _linkedItems = new List<IHierachy<IEntity>>(); 
       } 
       return _linkedItems; 
      } 
     } 
     #endregion 
    } 


    public class Item : Entity 
    { 
    } 

    public class MetaItem : Entity 
    { 
    } 

} 

以下是我的测试类 -

public class Test 
{ 
    public void Test1() 
    { 
     MetaItem meta1 = new MetaItem() { Id = 1, Name = "MetaItem1"}; 

     MetaItem meta2 = new MetaItem() { Id = 1, Name = "MetaItem 1.1"}; 

     Item meta3 = new Item() { Id = 101, Name = "Item 1" }; 


     **meta1.ChildItems.Add(meta3);** // this line should not compile. 
     meta1.ChildItems.Add(meta2) // This is valid and gets compiled. 
    } 
} 

在测试类,当我buidling父子关系,我可以添加项目作为元项目对象的子对象。在这里我想编译错误生成。

有人可以帮助我做到这一点。

-Regards 拉吉

+0

如果元项目只是一个包含其他项目的项目,那么它不是真的只是一个项目反正,其中'T = Item'? – 2010-06-23 13:52:45

+2

与您的问题无关,但对于Entity.Id和Name,自动实施的属性是您的朋友。 – dahlbyk 2010-06-23 13:58:15

回答

0

为什么你不觉得这行应该编译?它看起来完全有效。

ChildItems列表是公开的。如果你不希望他们能够添加到列表中,那么你将需要包装自己的收藏或使用ReadOnlyCollection<IHierachy<IEntity>>

哦,你已经解决了你的问题。我认为解决方案是使实体类通用。

using System.Collections.Generic; 

namespace WpfApplication12 
{ 
    public interface IEntity 
    { 
     int Id { get; set; } 
     string Name { get; set; } 
    } 

    public interface IHierachy<T> 
    { 
     IHierachy<T> Parent { get; } 
     List<IHierachy<T>> ChildItems { get; } 
     List<IHierachy<T>> LinkedItems { get; } 
    } 

    public class Entity<T> : IHierachy<T>, IEntity 
    { 
     private int _id; 
     public int Id 
     { 
      get { return _id; } 
      set { _id = value; } 
     } 

     private string _name; 
     public string Name 
     { 
      get { return _name; } 
      set { _name = value; } 
     } 

     public IHierachy<T> _parent; 
     public IHierachy<T> Parent 
     { 
      get 
      { 
       return _parent; 
      } 
     } 

     private List<IHierachy<T>> _childItems; 
     public List<IHierachy<T>> ChildItems 
     { 
      get 
      { 
       if(_childItems == null) 
       { 
        _childItems = new List<IHierachy<T>>(); 
       } 
       return _childItems; 
      } 
     } 

     private List<IHierachy<T>> _linkedItems; 
     public List<IHierachy<T>> LinkedItems 
     { 
      get 
      { 
       if(_linkedItems == null) 
       { 
        _linkedItems = new List<IHierachy<T>>(); 
       } 
       return _linkedItems; 
      } 
     } 
    } 


    public class Item : Entity<Item> 
    { 
    } 

    public class MetaItem : Entity<MetaItem> 
    { 
    } 

    public class Test 
    { 
     public void Test1() 
     { 
      MetaItem meta1 = new MetaItem() { Id = 1, Name = "MetaItem1"}; 
      MetaItem meta2 = new MetaItem() { Id = 1, Name = "MetaItem 1.1"}; 
      Item meta3 = new Item() { Id = 101, Name = "Item 1" }; 

      meta1.ChildItems.Add(meta3); // this line should not compile. 
      meta1.ChildItems.Add(meta2); // This is valid and gets compiled. 
     } 
    } 

} 
+0

我认为他不想允许添加Item作为MetaItem的子项(尽管代码明智,都是Entity类型)。换句话说,只有MetaItem.ChildItems应该只包含其他的MetaItem。我不熟悉实体的东西,所以我的猜测是将ChildItem更改为MetaItem的列表... – Alan 2010-06-23 13:55:10

+0

啊,是的,他已经解决了这个问题,你完全正确。您需要使Entities/Hierachies更通用。我正在修复我的解决方案。 – 2010-06-23 14:05:04

3

的代码被编译因为ChildItemsIList<Entity>,其中既包括ItemMetaItem。如果你是做Entity通用:

public class Entity<T> : IHierachy<T>, IEntity where T : IEntity { ... } 

那么就需要定义ItemMetaItem这样的:

public class Item : Entity<Item> { } 

public class MetaItem : Entity<MetaItem> { } 

在这种情况下,他们的ChildItems将是正确的,更受限制,类型。

+0

好的,我在'Entity '内将'IEntity'的引用更改为'T'后,我得到了它的工作。继承自己的专业化是一项有趣的技术。 – 2010-06-23 14:18:25

+0

是的,完成'实体'变化是作为一个练习。 :)绝对是一个有用的技术,为特定的场景。 – dahlbyk 2010-06-23 14:20:12

+0

Hi dahlbyk, Ya。在上面添加必要的更改会使其工作完美无缺。 谢谢。 – Raj 2010-06-23 14:25:37