简体   繁体   English

C#泛型和集合

[英]C# generics and collection

I have two objects MetaItems and Items. 我有两个对象MetaItems和Items。

MetaItem is template for objects and Items contains actual values. MetaItem是对象的模板,Items包含实际值。 For example "Department" is treated as meta-item and "Sales", "UK Region", "Asia Region" are treated as items. 例如,“部门”被视为元项目,“销售”,“英国地区”,“亚洲地区”被视为项目。

Additionally I want to maintain parent-child relation on these meta-items and items. 另外,我想在这些元项和项目上保持父子关系。

I have following code for same - 我有以下代码 -

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

}

Following is my test class - 以下是我的测试课 -

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

In the test class, when I am buidling parent-child relation, I can add item as a child object for meta-item object. 在测试类中,当我建立父子关系时,我可以将项添加为元项对象的子对象。 Here I want compilation error to be generated. 在这里,我希望生成编译错误。

Can someone help me in achiving this. 有人可以帮助我实现这个目标吗?

-Regards Raj -Regards Raj

The code is compiling because ChildItems will be IList<Entity> , which includes both Item and MetaItem . 代码正在编译,因为ChildItems将是IList<Entity> ,其中包括ItemMetaItem If you were to make Entity generic: 如果你要使Entity通用:

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

Then you would define Item and MetaItem like this: 然后你将像这样定义ItemMetaItem

public class Item : Entity<Item> { }

public class MetaItem : Entity<MetaItem> { }

In which case their ChildItems would be of the correct, more restricted, type. 在这种情况下,他们的ChildItems将是正确的,更受限制的类型。

Why don't you think that line should compile? 你为什么不认为这行应该编译? It looks completely valid. 它看起来完全有效。

The ChildItems list is public. ChildItems列表是公开的。 If you don't want them to be able to add to the list then you will need to wrap your own collection or use the ReadOnlyCollection<IHierachy<IEntity>> . 如果您不希望它们能够添加到列表中,那么您将需要包装自己的集合或使用ReadOnlyCollection<IHierachy<IEntity>>

Oh, you have fixed your question. 哦,你已经解决了你的问题。 I think the solution is to make the Entity class generic. 我认为解决方案是使Entity类通用。

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM