Declaring variables of generic types

Declaring variables of generic types

Old forum URL: forums.lhotka.net/forums/t/3368.aspx


Hiren posted on Monday, August 13, 2007

Hi,

My projects requires that the UI have a class called 'ApplicationFolder' as a base class which can be used to subclass various other ApplicationFolders such as ContactsFolder, SuppliersFolder etc.

Now my problem is that the ApplicationFolder base class has to have a property called 'Datasource' which exposes a 'ReadOnlyListBase' type of an object. So the subclasses ContactsFolder, SuppliersFolder will have ContactsList, SuppliersList as the corresponding datasources.

How can I define a variable in my 'ApplicationFolder' base class which is of type ReadOnlyBaseList<T> where T is of type ReadOnlyBase?

Thanks in advance for the tips,

Hiren

JoeFallon1 replied on Monday, August 13, 2007

Here is one idea:

Protected mReadOnlyList As IReadOnlyCollection
Protected mReadOnlyBO As IReadOnlyObject

Public Overridable Function GetReadOnlyBO() As IReadOnlyObject
  Dim mRO As SomeBaseRO
  mRO = SomeBaseRO.NewSomeBaseRO
  'set some properties here
  Return mRO
End Function

Public Overridable Function GetROC() As IReadOnlyCollection
  Return
Nothing
End
Function

=================================================================================

In the subclasses you can override either method and do things like:

Public Overrides Function GetROC() As IReadOnlyCollection
  Return SomeRealROC.GetSomeRealROC("", Me.ID)
End Function

You can also add other propeties and methods to a subclass of the IReadOnlyCollection Interface and then attempt to use this new subclass of the collection interface in your base class. Save you from coding things in each concrete class. You can always cast the interface to the actual concrete type too.

Joe


 

Hiren replied on Monday, August 13, 2007

JoeFallon1:

Here is one idea:

Protected mReadOnlyList As IReadOnlyCollection
Protected mReadOnlyBO As IReadOnlyObject

Public Overridable Function GetReadOnlyBO() As IReadOnlyObject
  Dim mRO As SomeBaseRO
  mRO = SomeBaseRO.NewSomeBaseRO
  'set some properties here
  Return mRO
End Function

Public Overridable Function GetROC() As IReadOnlyCollection
  Return
Nothing
End
Function

=================================================================================

In the subclasses you can override either method and do things like:

Public Overrides Function GetROC() As IReadOnlyCollection
  Return SomeRealROC.GetSomeRealROC("", Me.ID)
End Function

You can also add other propeties and methods to a subclass of the IReadOnlyCollection Interface and then attempt to use this new subclass of the collection interface in your base class. Save you from coding things in each concrete class. You can always cast the interface to the actual concrete type too.

Joe


 

Thanks for the tip Joe, but my problem is as follows:

I've extend Rocky's base classe 'ReadOnlyListBase' as follows:

public abstract class MyReadOnlyListBase<T, C> : Csla.ReadOnlyListBase<T, C>
where T : Csla.ReadOnlyListBase<T, C>
where C : Csla.ReadOnlyBase<C>
{
protected abstract void Refresh();
}

So, all my ReadOnlyListBase classes should override the 'Refresh' method. Having done that,

in my ApplicationFolder class, I now want to have the ability to define a member variable as such:

private MyReadOnlyListBase _datasource;

public void Refresh(){
   _dataSource.Refresh();
}

I can't somehow determine how to be able to declare a variable of type 'MyReadOnlyListBase', given that I don't know the types for T and C.

I hope I'm making myself understood in this case.

Thanks,

Hiren

McManus replied on Monday, August 13, 2007

Hiren,

You can't have polymorphism when using a generic base class. However, you can define an interface (for instance IRefresh) that has one method:

public interface IRefresh
{
   void Refresh();

}

Then implement this interface in your base class (make sure that T must inherit from MyReadOnlyListBase<T,C> instead of Csla.ReadOnlyListBase<T,C>):

public abstract class MyReadOnlyListBase<T, C> : Csla.ReadOnlyListBase<T, C>, IRefresh
   where T : MyReadOnlyListBase
<T, C>
   where C : Csla.ReadOnlyBase
<C>
{
   protected abstract void Refresh();

   void IRefresh.Refresh()
   {
      this.Refresh();
   }
}

Now you can have the following code in your ApplicationFolder class:

   private IRefresh _dataSource;

   public void Refresh()
   {
      _dataSource.Refresh();
   }

Cheers,
Herman

JoeFallon1 replied on Monday, August 13, 2007

Thanks Herman.

You gave him the code sample that I was describing in my rambling post.

I suggested extending the Interface and adding whatever methods he needs.

But it is much clearer in your post.

Joe

 

Hiren replied on Wednesday, August 15, 2007

Thanks, that makes it clear!!

Herman & Joe, thanks a ton for your time and inputs!

Cheers,

Hiren

Copyright (c) Marimer LLC