Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Abstract Generic class?
Message
From
13/10/2009 07:54:18
 
 
To
13/10/2009 00:16:44
General information
Forum:
ASP.NET
Category:
Class design
Environment versions
Environment:
C# 3.0
Miscellaneous
Thread ID:
01429024
Message ID:
01429105
Views:
34
>>Hi,
>>
>>I have a generic class - in a cutdown form so:
public class BaseTVItemViewModel<U> : ViewModelBase
>>     where U : EntityObject
>>    {
>>        Interfaces.IsTreeModel<U> _treeModel;
>>        List<BaseTVItemViewModel<U>> _children;
>>        BaseTVItemViewModel<U> _parent;
>>
>>        public BaseTVItemViewModel(Interfaces.IsTreeModel<U> tm)
>>        {
>>            _treeModel = tm;
>>        }
>>
>>       public BaseTVItemViewModel<U> Parent
>>        {
>>            get
>>            {
>>                if (_parent == null)
>>                {
>>                    _parent = new BaseTVItemViewModel<U>((Interfaces.IsTreeModel<U>)_treeModel);
>>                }
>>                return _parent;
>>            }
>>            set { _parent = value; }
>>        }
>>
>>        public List<BaseTVItemViewModel<U>> Children
>>        {
>>            get
>>            {
>>                if (_children == null)
>>                {
>>                    _children = new List<BaseTVItemViewModel<U>>();
>>
>>                    foreach (U u in _treeModel.GenericChildren)
>>                    {
>>                        _children.Add(new BaseTVItemViewModel<U>((Interfaces.IsTreeModel<U>)u));
>>                    }
>>                }
>>                return _children;
>>            }
>>
>>        }
>>
>>        public virtual void LoadItems()
>>        {
>>        }
>>    }
>>
I wanted to make the LoadItems() method abstract but I can't make the class abstract because constructing a new instance of an abstract class (as in the Children property) isn't allowed :-{
>>
>>Is there a better way of designing this?
>>TIA,
>>Viv
>
>Viv,
>
>(1) As you have found out: If a class is abstract, then there are parts missing and it cannot be instantiated
>
>(2) Once subclassed, what will become of the new BaseTVItemViewModel() ?
>The classname won't be correct anymore - or doesn't that matter ?
>
>
>Solutions
>(1) Like Bonnie says
>
>(2) Add another abstract method which returns a new instance
>Since the method is abstract - I have discovered it cannot be static - Create() is usually static
>
>You now have two abstract methods: LoadItems() and Create()
>
>
>	abstract class AbstractBaseClass
>	{
>		protected AbstractBaseClass Child = null;
>		//______________________________________________________________________
>		public abstract AbstractBaseClass Create();
>		//______________________________________________________________________
>		public abstract void LoadItems();
>		//______________________________________________________________________
>		public void xx()
>		{
>			Child = Create();
>		}
>		//______________________________________________________________________
>
>	}
>
>	class DerivedClass : AbstractBaseClass
>	{
>		//______________________________________________________________________
>		public override AbstractBaseClass Create()
>		{
>			return new DerivedClass();  // or AbstractBaseClass()
>		}
>		//______________________________________________________________________
>		public override void LoadItems()
>		{
>			Child = Create(); // 
>		}
>
>	}
>
Hi,
I thought about that approach but I'm currently playing with extending the generic nature of the class:
public abstract class BaseTVItemViewModel<U,C> : ViewModelBase
     where U : EntityObject
     where C : BaseTVItemViewModel<U,C>, new()
    {
         protected Interfaces.IsTreeModel<U> _treeModel;
        List<C> _children;
        C _parent;

        public BaseTVItemViewModel() { }

        public BaseTVItemViewModel(Interfaces.IsTreeModel<U> tm)
        {
            _treeModel = tm;
        }

        public C Parent
        {
            get
            {
                if (_parent == null)
                {
                    _parent = CreateInstance((IsTreeModel<U>) _treeModel.Parent);
                }
                return _parent;
            }
            set { _parent = value; }
        }

        public List<C> Children
        {
            get
            {
                if (_children == null)
                {
                    _children = new List<C>();

                    foreach (U u in _treeModel.GenericChildren)
                    {
                        _children.Add(CreateInstance((IsTreeModel<U>)u));
                    }
                }
                return _children;
            }
        }

        public  C CreateInstance(Interfaces.IsTreeModel<U> u)
        {
            C  x= new C();
            x._treeModel = u;
            x.Initialize((U) u);
            return x;
        }

        public abstract void Initialize(U u);
    }
Seems to work. This way my sub-classes look like:
   public class UIItemTVModel : BaseTVItemViewModel<UIItem,UIItemTVModel>
    {
        private string _description;
        private EntityCollection<UIItemRestrictions> _uir;

        public UIItemTVModel() { }

        public UIItemTVModel(UIItem u)
            : base(u)
        {
            Initialize(u);
        }

        public override void Initialize(UIItem u)
        {
            _description = u.Description;
            _uir = u.Restrictions;
        }
     }
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform