C#泛型和集合

C#泛型和集合,c#,generics,collections,C#,Generics,Collections,我有两个对象:元项和项 MetaItem是对象的模板,项包含实际值。例如,“部门”被视为元项目,“销售”、“英国地区”、“亚洲地区”被视为项目 此外,我希望维护这些元项和项的父子关系 我有以下相同的代码- using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WpfApplication12 { public interface IEntity

我有两个对象:元项和项

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

此外,我希望维护这些元项和项的父子关系

我有以下相同的代码-

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

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

有人能帮我做到这一点吗

-问候
Raj

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

ChildItems列表是公共的。如果您不希望他们能够添加到列表中,则需要包装您自己的集合或使用
ReadOnlyCollection

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

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

}
使用System.Collections.Generic;
命名空间WpfApplication12
{
公共界面的开放性
{
int Id{get;set;}
字符串名称{get;set;}
}
公共接口IHierachy
{
IHierachy父项{get;}
列出子项{get;}
列出LinkedItems{get;}
}
公共类实体:IHierachy、IEntity
{
私人内部id;
公共整数Id
{
获取{return\u id;}
设置{u id=value;}
}
私有字符串\u名称;
公共字符串名
{
获取{return\u name;}
设置{u name=value;}
}
公立高等学校家长;
公立医院家长
{
得到
{
返回父母;
}
}
私人物品清单;
公共子项列表
{
得到
{
if(_childItems==null)
{
_childItems=新列表();
}
返回子项;
}
}
私人名单(linkedItems);;
公共列表链接数据项
{
得到
{
如果(_linkedItems==null)
{
_linkedItems=新列表();
}
返回链接数据项;
}
}
}
公共类项:实体
{
}
公共类元项:实体
{
}
公开课考试
{
公共void Test1()
{
MetaItem meta1=新的MetaItem(){Id=1,Name=“MetaItem1”};
MetaItem meta2=新的MetaItem(){Id=1,Name=“MetaItem 1.1”};
Item meta3=new Item(){Id=101,Name=“Item 1”};
meta1.ChildItems.Add(meta3);//此行不应编译。
meta1.ChildItems.Add(meta2);//这是有效的,可以编译。
}
}
}

代码正在编译,因为
ChildItems
将是
IList
,其中包括
项和
元项。如果要使
实体
通用:

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

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

如果元项只是一个包含其他项的项,那么它实际上不就是一个项吗,其中
t=item
?与您的问题无关,但是对于Entity.Id和Name,自动实现的属性是您的朋友。我认为他不希望允许将项作为MetaItem的子项添加(即使在代码方面,两者都是Entity类型)。换句话说,只有MetaItem.ChildItems应该只包含其他MetaItem。我不熟悉实体的东西,所以我猜应该把ChildItem改为元项列表……啊,是的,他已经解决了这个问题,你完全正确。您需要使实体/层次结构更通用。我现在正在修复我的解决方案。好的,在将
Entity
中对
Entity
的引用更改为
T
之后,我让它开始工作了。继承自己的专长是一项有趣的技术。是的,完成
实体
更改只是一项练习。:)对于特定场景来说,这绝对是一种有用的技术。嗨,dahlbyk,是的。在上述基础上增加必要的改动,使其工作更加完美。谢谢
public class Entity<T> : IHierachy<T>, IEntity where T : IEntity { ... }
public class Item : Entity<Item> { }

public class MetaItem : Entity<MetaItem> { }