Reputation: 51
I have two objects MetaItems and Items.
MetaItem is template for objects and Items contains actual values. 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
Upvotes: 5
Views: 241
Reputation: 4867
Why don't you think that line should compile? It looks completely valid.
The ChildItems list is public. 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>>
.
Oh, you have fixed your question. I think the solution is to make the Entity class generic.
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.
}
}
}
Upvotes: 0
Reputation: 77530
The code is compiling because ChildItems
will be IList<Entity>
, which includes both Item
and MetaItem
. If you were to make Entity
generic:
public class Entity<T> : IHierachy<T>, IEntity where T : IEntity { ... }
Then you would define Item
and MetaItem
like this:
public class Item : Entity<Item> { }
public class MetaItem : Entity<MetaItem> { }
In which case their ChildItems
would be of the correct, more restricted, type.
Upvotes: 3