Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Abstract Generic class?
Message
De
13/10/2009 08:39:57
 
 
À
13/10/2009 07:54:18
Information générale
Forum:
ASP.NET
Catégorie:
Conception classe
Versions des environnements
Environment:
C# 3.0
Divers
Thread ID:
01429024
Message ID:
01429113
Vues:
44
>>>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;
>        }
>     }

(1) Generics are nice and fine, but sometimes the mind needs a boost to see how to put them together

(2)
Can you move Initialize(u); into the parent class ? ( I may be wrong - difficult to follow the class/subclass/generic logic when you didn't write it yourself)

Parent
>        public BaseTVItemViewModel(Interfaces.IsTreeModel<U> tm)
>        {
>            _treeModel = tm;
              Initialize(tm);
>        }
Then the constructor of the derived class would become
>        public UIItemTVModel(UIItem u)
>            : base(u)
>        {
>          //  not needed  Initialize(u);
>        }
>
Gregory
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform