Gillardo
Gillardo

Reputation: 9818

Convert object of generic type T to a specific type

I have declared a base class (using CSLA.NET ) as such

Public Class EditableBase(Of T As EditableBase(Of T))
    Inherits BusinessBase(Of T)

End Class

I have my Company class which is inheriting from this base and is declared as so

<Serializable()> _
Public Class Company
    Inherits EditableBase(Of Company)

End Class

Now in my code, i need to check if the type is of type Company, which i can do like so

If GetType(T) Is GetType(Company) Then

But how can i cast the object as this type? I have tried

Dim lObject As Company = DirectCast(Me, Company)

But this seems to error with the message

Value of type 'T' cannot be converted to type Company

Upvotes: 2

Views: 3106

Answers (2)

John
John

Reputation: 6553

It sounds like you need to implement either from an Interface or a base class and not a Generic (T). Generics are by design supposed to be very open to different types while what you are doing is trying to limit it to a subset of classses, and thus should either use a base class or interface.

Upvotes: 1

Steven Doggart
Steven Doggart

Reputation: 43743

If the EditableBase class is doing something like this, it clearly won't work:

If GetType(T) Is GetType(Company) Then
    Dim o As Company = DirectCast(Me, Company)  ' Fails to compile
End If

You can't do that because Me is obviously an instance of EditableBase(Of Company). You can't automatically convert from EditableBase(Of T) to Company. The compiler knows the types and it knows that they aren't compatible, so it doesn't allow it. However, since you know, in this case, that T is Company, and Company does inherit from EditableBase(Of Company), you can trick it into working by first casting to Object. The compiler will always allow you to cast from Object to anything else.

If GetType(T) Is GetType(Company) Then
    Dim o As Company = DirectCast(DirectCast(Me, Object), Company)  ' Compiles successfully
End If

However, all of this seems to me like signs of a bad design. First, having T be constrained in that way is rather bizarre. Also, having the base class check for specific concrete types of the derived classes, like that, is almost certainly a sign that it could be designed in a better way.

By definition, base classes should always act in the same way, regardless of the type of the derived class. If, for some reason, it must, then the inheritance relationship isn't really true at all. If, for instance, a base class called Animal has conditional logic which causes it to act differently when it's a Cat, then you can't really logically say that both Cat and Dog are types of Animal. It's like saying an animal is something that's alive, except when it's not, in which case sometimes it is too. I suppose it's possible to define something that way, but it becomes a meaningless definition.

Similarly, generic classes should not act differently depending on the type of their generic type arguments (i.e. T). If, for some reason, they must, then they aren't really generic at all.

Upvotes: 3

Related Questions