typeof( BusinessBase<T> ) ???

typeof( BusinessBase<T> ) ???

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


dredge posted on Tuesday, May 09, 2006

In previous CSLA versions, I would use typeof(BusinessBase) quite often, to ensure the object I was looking at was a BusinessBase CSLA object. With the new generics in place, I can't call typeof(BusinessBase<T>) without knowing the actual Type that T is. This presents a problem, because I don't know the Type... I just know that I want to ensure it's a BusinessBase.

Should I be using typeof(Core.BusinessBase) since this is a concrete class that BusinessBase<T> inherits from? or is there a way to use typeof(Businessbase<T>) without knowing the actual T type?

xal replied on Tuesday, May 09, 2006

Well, it took me some time to find it, but I did!
Here's a link to a thread where I posted a solution to your problem not long ago:
http://www.searchcsla.com/Details.aspx?msn_id=26406


It made me mad too :D

Andrés

Jav replied on Tuesday, May 09, 2006

You should be creating your BusinessBase derived classes like this

Public Class MyClass
         Inherits Csla.BusinessBase(Of MyClass)

Now if you want to check theType of an object  you can use

If TypeOf obj Is MyClass Then
      .......

Jav

dredge replied on Tuesday, May 09, 2006

Jav,

Thanks for the info, but you're a little off. Both of you assume that I have a specific type derived from BusinessBase, that I am checking against. I am trying to check against BusinessBase directly, not a derived type.

FYI - I found two ways of working this.

1) My previous thought of using Core.BusinessBase works just fine.

2) Type t = typeof(BusinessBase<>); if (obj.GetType().IsSubClassOf(t)){ do something }

I wasn't aware that I could use typeof(BusinessBase<>) without specifying a Type T in the <>, previously. Thanks to Xal for his post pointing me in this direction.

This doesn't completley solve my problem, though. I also want to be able to convert an object from Objct type, to BusinessBase<T> type, without knowing the <T> Type...

BusinessBase<> obj = (BusinessBase<>)

This code doesn't work, and I haven't quite figured out if I can work around this, without using Core.BusinessBase.

Mark replied on Tuesday, May 09, 2006

It sounds like you're trying to get polymorphic behavior out of a generic - which is going to cause all sorts of headaches, since generics aren't polymorphic (as you've discovered).

What is your goal in casting from object to BusinessBase<T>?  If it's to access common functions across all your business objects, either use Core.BusinessBase or create your own interface that defines the common functions you wish to call (let's say ICustomBusinessObject or some such...)

 

 

Jav replied on Tuesday, May 09, 2006

aaah.  There is also the Interface iBusinessObject, have you tried using (vb) If TypeOf obj Is Csla.Core.IBusinessObject Then ....

Jav

xal replied on Tuesday, May 09, 2006

I'm intrigued... why exactly do you need to cast to BusinessBase<> ?
There are some interfaces that can help you, but.... are you by any chance trying to create custom controls? or classes / methods that do something to your business objects?

If that's the case, why not go the generic route?

If it's a method, its as easy as using a constraint in the method (such as Dataportal methods have)

Something like
Public Sub SaveMyBO(Of T as Csla.BusinessBase(Of T))(ByVal bo as T)
bo.Save()
End Sub

Constraints in c# use a where clause instead of "as" like vb does.


If it's a class then it's the same thing. Although if it's controls / forms inheritance that you're after, then you'll want to read this:
http://groups.msn.com/cslanet/general.msnw?action=get_message&mview=0&ID_Message=26430&LastModified=4675571209386681035


Andrés

dredge replied on Tuesday, May 09, 2006

the basic scenario is that I've got a method that accepts an Object parameter. If this parameter is derived from BusinessObject, then I need to get to the methods on that BusinessObject. If the Object is not a BusinessObject, then i do other stuff with it.

The basic code i wanted was:

public void MyMethod(object obj){
  if (obj.GetType().IsSubClassOf(typeof(BusinessBase<>)){
    DoWorkHere();
  }
}

And that all works fine... except, that I wanted to be able to cast the Object parameter to a BusinessBase<T> object directly, so I could call methods of BusinessBase<T>. But, like previous replies have stated, generics are not polymorphic, so I can't directly accomplish what I wanted. I ended up using Core.BusinessBase instead of BusinessBase<T> and it works fine.

public void MyMethod(object obj){
  if (obj.GetType().IsSubClassOf(typeof(BusinessBase<>)){
    Core.BusinessBase bb = (Core.BusinessBase)obj;
  }
}

Thanks to all for the pointers and responses. I wasn't aware that generics weren't polymorphic, previously.

DogSpots replied on Tuesday, May 09, 2006

Here's an article at MSDN that might help:
How to: Examine and Instantiate Generic Types with Reflection

This will allow you to write code to create a generic without knowing the exact type of the generic at design-time.  This is pretty powerful, but be sure you actually need it before you march off in this direction.  The whole point of generics is to give you a strongly typed object to work with and with this you are purposely circumventing that so that you can work with base objects instead.

I've used this technique to get around the fact that I cannot create a generic windows control.  When I set the datasource property of my control to a BusinessListBase<T,C>, I automatically create a generic helper object that is strongly typed to T and C whatever T and C might be.  Then, I interact with my helper instead of the control.

Good luck.

 

Copyright (c) Marimer LLC