I am trying to create a library that extends from a common base class that
provides common functionality, but I am running into one significant road
block. Let me give you an example.
If I do not do this with Generics, I would do something like this (Foo and
Bar extend from BaseClass):
public abstract class BaseClass
{
}
public class Foo : BaseClass
{
public override string ToString()
{
return "I am a Foo";
}
}
public class Bar : BaseClass
{
public override string ToString()
{
return "I am a Bar";
}
}
Then I could do some things like this:
Foo fooItem = new Foo();
Console.WriteLine(fooItem.ToString());
Bar barItem = new Bar();
Console.WriteLine(barItem.ToString());
And then add them to a common generic list like this:
List<BaseClass> listOfItems = new List<BaseClass>();
listOfItems.Add(fooItem);
listOfItems.Add(barItem);
foreach (BaseClass baseItem in listOfItems)
{
Console.WriteLine(baseItem.ToString());
}
The list of abstract base class items is a concrete class. But now I want
to make the base class generic, to have access to the type information like
this:
public abstract class BaseClass<T> where T : BaseClass<T>
{
public override string ToString()
{
return "I am a " + typeof(T).Name;
}
}
public class Foo : BaseClass<Foo>
{
}
public class Bar : BaseClass<Bar>
{
}
I can still do this, and it works:
Foo fooItem = new Foo();
Console.WriteLine(fooItem.ToString());
Bar barItem = new Bar();
Console.WriteLine(barItem.ToString());
But when I try to define a list of abstract base class items like:
List<BaseClass<>> listOfItems = new List<BaseClass<>>();
It expects a type parameter to be supplied. I can make it a list of
BaseClass<Foo> or BaseClass<Bar> but I want the list to be able to contain
either type. I could make the list of object, but then I don't have the
ability to restrict the type to Foo or Bar. I think what I am looking for is
a contraint that I can place on the type supplied to the list but there does
not seem to be any syntax for this.
Am I missing something in working with Generics?
Jim
Ciaran O''Donnell - 13 Nov 2006 15:37 GMT
Your not missing anything apart from the diffculty in building generics to
work the way you want. BaseClass<Foo> does not inherit from BaseClass<T>,
its a different type.
Ciaran
> I am trying to create a library that extends from a common base class that
> provides common functionality, but I am running into one significant road
[quoted text clipped - 84 lines]
>
> Jim
jkitagr - 13 Nov 2006 15:55 GMT
But when I call Foo.ToString() it is clearly calling BaseClass<T>.ToString()
so it is extending from the generic base class. Is that not what you mean?
Jim
> Your not missing anything apart from the diffculty in building generics to
> work the way you want. BaseClass<Foo> does not inherit from BaseClass<T>,
> its a different type.
>
> Ciaran
Ciaran O''Donnell - 14 Nov 2006 12:23 GMT
It doesnt inherit from BaseClass<T> but the compiler makes a class called
BaseClass<Foo> which is identicle to BaseClass<T> but is specialised rather
than generic. Thats the problem with what you want to do:
Foo : BaseClass<Foo>
BaseClass<Foo>:object
Bar : BaseClass<Bar>
BaseClass<Bar> : object
( : = inherits)
Ciaran O'Donnell
> But when I call Foo.ToString() it is clearly calling BaseClass<T>.ToString()
> so it is extending from the generic base class. Is that not what you mean?
[quoted text clipped - 6 lines]
> >
> > Ciaran
AJ - 13 Nov 2006 16:06 GMT
> I am trying to create a library that extends from a common base class that
> provides common functionality, but I am running into one significant road
[quoted text clipped - 45 lines]
> to make the base class generic, to have access to the type information like
> this:
You could have an abstract, non-generic base class from which BaseClass
<T> derives
i.e. class BaseClass<T> : BaseClass where T : BaseClass<T> {..}
and then have List<BaseClass> throughout.
Or, in a similar way, define an interface which BaseClass<T> implements,
and have a List<IBaseInterface>
I don't believe there's another way to achieve this, though. (Having hit
the same problem myself..)
jkitagr - 14 Nov 2006 21:00 GMT
Ciaran and AJ,
Thanks for your input. It has helped in my understanding of Generics and
inheritance.