C # дженерики и коллекция - PullRequest
5 голосов
/ 23 июня 2010

У меня есть два объекта MetaItems и Items.

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

В тестовом классе, когда я строю отношения родитель-потомок, я могу добавить элемент как дочерний объект для объекта мета-элемента. Здесь я хочу, чтобы генерировалась ошибка компиляции.

Может ли кто-нибудь помочь мне в достижении этого.

-Regards Радж

Ответы [ 2 ]

3 голосов
/ 23 июня 2010

Код компилируется, потому что ChildItems будет IList<Entity>, что включает в себя 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 будет иметь правильный, более ограниченный тип.

0 голосов
/ 23 июня 2010

Почему вы не думаете, что эта строка должна компилироваться? Это выглядит полностью действительным.

Список ChildItems является открытым. Если вы не хотите, чтобы их можно было добавить в список, вам нужно будет обернуть собственную коллекцию или использовать ReadOnlyCollection<IHierachy<IEntity>>.

О, вы исправили свой вопрос. Я думаю, что решение состоит в том, чтобы сделать класс 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.
        }
    }

}
...