Reputation: 1020
I have these 3 abstract classes:
public abstract class DataObject {}
public abstract class BusinessObject<T> where T : DataObject {}
public abstract class UIObject<T> where T : BusinessObject<DataObject> {}
I am able to create a CustomerDataObject which derives from DataObject
, a CustomerBusinessObject which derives from BusinessObject<CustomerDataObject>
but I can't create the CustomerUIObject class:
The type
CustomerBusinessObject
cannot be used as type parameterT
in the generic type or methodUIObject<T>
. There is no implicit reference conversion fromCustomerBusinessObject
toBusinessObject<DataObject>
.
What am I doing wrong?
Upvotes: 2
Views: 169
Reputation: 148514
For Why
- you already know
Now there is a way that you can do it - without changing logic :
You can add double constraint :
public abstract class DataObject {}
public abstract class BusinessObject<T> where T : DataObject {}
public abstract class UIObject<T,U> where T : BusinessObject<U> where U:DataObject {}
This way you explicitly tell the compiler that U
can be a type that derive from DataObject
- which is exactly what your CustomerDataObject
is.
But you will need to add :
class CustomerDataObject:DataObject
{}
class CustomerBusinessObject :BusinessObject<CustomerDataObject>
{}
class CustomerUIObject :UIObject<CustomerBusinessObject,CustomerDataObject>
{}
This way you're specifying the CustomerDataObject
which inherits from DataObject
which is exactly what you meant at first place
Upvotes: 2
Reputation: 2246
you have to use Generics contraints to resolve this issue.
public abstract class UIObject<T,U> where T : BusinessObject<U>
Upvotes: 1
Reputation: 3681
You are explicitly stating that the T for UIObject
inherits BusinessObject<DataObject>
but your type CustomerBusinessObject
actually inherits BusinessObject<CustomerDataObject>
which is a different type.
Can you have CustomerBusinessObject
inherit BusinessObject<DataObject>
but then in the implementation always use CustomerDataObject
? That would fix this error but might not be quite what you want.
public class CustomerBusinessObject : BusinessObject<DataObject> { }
Upvotes: 2