Inherit from generic class type

B

butch77

Hi!
I'd like to create a class, that inherits from a generic class type:

public class CompoundObject<T> : T where T : ObjectBase { [...] }

C# won't let me do it. and gives me the CS0689 error
I understand the compile time issue as mentioned in
http://www.thescripts.com/forum/thread447666.html

But:
1. Here I'm defining T to derive from ObjectBase, so at least there
would be a few methods to override etc.
2. The compiler should rather throw an error when trying to create the
specific generic class, chekcing whether there are any clashes with
that specific class used as type Parameter with the actual object.

In case anyone knows a workaround let me know of course.

Cheers.
 
A

Anthony Jones

Peter Duniho said:
Hi!
I'd like to create a class, that inherits from a generic class type:

public class CompoundObject<T> : T where T : ObjectBase { [...] }

C# won't let me do it. and gives me the CS0689 error
I understand the compile time issue as mentioned in
http://www.thescripts.com/forum/thread447666.html

But:
1. Here I'm defining T to derive from ObjectBase, so at least there
would be a few methods to override etc.

Sure, as in the example posted in that thread too (well, if you fix the
example so that the "Solid" and "Gradient" classes actually inherit the
"Base" class as I assume the poster meant them to). Makes sense.
2. The compiler should rather throw an error when trying to create the
specific generic class, chekcing whether there are any clashes with
that specific class used as type Parameter with the actual object.

As explained in that thread, it's not an issue of a conflict (or at least
I think I agree with the person who wrote that it's not). It's a question
of what information the compiler has at the time it compiles the generic
class. It needs to be able to verify the generic class as fundamentally
correct, and the correct compilation of other code using the generic class
needs to be compilable without looking at anything other than the generic
interface exposed by the class.

It can't do that if CompoundObject<T> actually inherits from the base type.
In case anyone knows a workaround let me know of course.

Well, as was also mentioned in that thread, composition is a fine
alternative. And in fact, would not be hard at all. Instead of:

class CompoundObject<T> : T where T : ObjectBase
{
// ...
}

instead use:

class CompoundObject<T> where T : ObjectBase
{
private T _t;
}

Then you get at the methods in ObjectBase that you want to use by calling
them on _t. If you want for CompoundObject<T> to expose the same
interface that ObjectBase does, you can simply define the same members in
CompoundObject<T> and delegate their actual operation to the _t object.

Of course it means you need a way of instantiating T or being provided one
somehow. But that's not difficult to solve either (the most obvious way
would be to add the "new()" constraint as well, but of course ObjectBase
could define some sort of factory, or the instantiator of the
CompoundObject<T> could pass in an appropriate instance of T to use, as
other examples).

It's hard to offer very specific advice without knowing exactly what
you're trying to do. But if all you're wanting to do is something similar
to the "strategy pattern" example posted in that thread, I think the above
should suffice.


You could also make a small adjustment with :-

class CompoundObject<T> : ObjectBase where T : ObjectBase
{
private T myT;
}

Now you can override members of ObjectBase and delegate them to myT.
Of course this something a little more than a strategy pattern.
 
B

butch77

Hi!
I'd like to create a class, that inherits from a generic class type:
public class CompoundObject<T> : T where T : ObjectBase { [...] }
C# won't let me do it. and gives me the CS0689 error
I understand the compile time issue as mentioned in
http://www.thescripts.com/forum/thread447666.html
But:
1. Here I'm defining T to derive from ObjectBase, so at least there
would be a few methods to override etc.

Sure, as in the example posted in that thread too (well, if you fix the
example so that the "Solid" and "Gradient" classes actually inherit the
"Base" class as I assume the poster meant them to). Makes sense.
2. The compiler should rather throw an error when trying to create the
specific generic class, chekcing whether there are any clashes with
that specific class used as type Parameter with the actual object.

As explained in that thread, it's not an issue of a conflict (or at least
I think I agree with the person who wrote that it's not). It's a question
of what information the compiler has at the time it compiles the generic
class. It needs to be able to verify the generic class as fundamentally
correct, and the correct compilation of other code using the generic class
needs to be compilable without looking at anything other than the generic
interface exposed by the class.

It can't do that if CompoundObject said:
In case anyone knows a workaround let me know of course.

Well, as was also mentioned in that thread, composition is a fine
alternative. And in fact, would not be hard at all. Instead of:

class CompoundObject<T> : T where T : ObjectBase
{
// ...
}

instead use:

class CompoundObject<T> where T : ObjectBase
{
private T _t;
}

Then you get at the methods in ObjectBase that you want to use by calling
them on _t. If you want for CompoundObject<T> to expose the same
interface that ObjectBase does, you can simply define the same members in
CompoundObject<T> and delegate their actual operation to the _t object.

Of course it means you need a way of instantiating T or being provided one
somehow. But that's not difficult to solve either (the most obvious way
would be to add the "new()" constraint as well, but of course ObjectBase
could define some sort of factory, or the instantiator of the
CompoundObject<T> could pass in an appropriate instance of T to use, as
other examples).

It's hard to offer very specific advice without knowing exactly what
you're trying to do. But if all you're wanting to do is something similar
to the "strategy pattern" example posted in that thread, I think the above
should suffice.

Pete

Thanks!!
Even though I'm not happy about the answer, I guess we're just limited
to the capabilities of the C# compiler.

Ceers!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top