【问题标题】:C# generics and collectionC# 泛型和集合
【发布时间】:2010-06-23 13:47:25
【问题描述】:

我有两个对象 MetaItems 和 Items。

MetaItem 是对象的模板,Items 包含实际值。例如,“Department”被视为元项目,“Sales”、“UK Region”、“Asia Region”被视为项目。

此外,我想在这些元项目和项目上保持父子关系。

我有以下相同的代码 -

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.
    }
}

在测试类中,当我建立父子关系时,我可以将项目添加为元项目对象的子对象。在这里,我希望生成编译错误。

谁能帮我实现这个目标。

-问候 拉杰

【问题讨论】:

  • 如果一个元项目只是一个包含其他项目的项目,那么它不只是一个项目,T = Item?
  • 与您的问题无关,但对于 Entity.Id 和 Name,自动实现的属性是您的朋友。

标签: c# generics collections


【解决方案1】:

代码正在编译,因为ChildItems 将是IList&lt;Entity&gt;,其中包括Item 和MetaItem。如果您要使Entity 通用:

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

然后您将像这样定义Item 和MetaItem:

public class Item : Entity<Item> { }

public class MetaItem : Entity<MetaItem> { }

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

【讨论】:

  • 好的,在将Entity&lt;T&gt; 中对IEntity 的引用更改为T 之后,我开始工作了。继承自己的专长是一项有趣的技术。
  • 是的,完成Entity&lt;T&gt; 更改留作练习。 :) 对于特定场景来说绝对是一种有用的技术。
  • 嗨,达尔比克,是的。通过上述更改添加必要的更改其工作完美。谢谢。
【解决方案2】:

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

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

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

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.
        }
    }

}

【讨论】:

  • 我认为他不想允许将 Item 添加为 MetaItem 的子项(即使代码明智,两者都是实体类型)。换句话说,只有 MetaItem.ChildItems 应该只包含其他 MetaItem。我不熟悉实体的东西,所以我的猜测是将 ChildItem 更改为 MetaItems 列表......
  • 啊,是的,他已经解决了这个问题,你是完全正确的。您需要使实体/层次结构更通用。我现在正在修复我的解决方案。
猜你喜欢
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 2017-12-24
相关资源
最近更新 更多