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

I think mine needs more than a boost - maybe a complete re-wire :-}

>(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)

'Initialize((U) tm);' works - but I think it's six of one / half dozen of the other ?
Regards,
Viv


>
>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);
>>        }
>>
>
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform