Reputation: 1885
I have a simple class structure
abstract class A {
List<A> containerList;
...
}
class B : A {....}
class C : A {....}
I make sure that the containerList
contains only elements of class B
or C
(as the list is filled in these child classes and A
is abstract).
Now, I'd like, somehow, to have a base property / method in A
which would cast itself to whatever the real type of the object is, i.e. B
or C
. Having an abstract method is just fine, but it is important to get a Collection<T>
of B
or C
objects, as I have bindings that will depend on it.
Upvotes: 1
Views: 51
Reputation: 43886
You could use generics like that (though it looks a little strange):
public abstract class A<T> where T : A<T>
{
protected List<A<T>> containerList;
public Collection<T> ContainerList
{
get { return new Collection<T>(containerList.OfType<T>().ToList()); }
}
}
public class B : A<B>
{
//...
}
public class C : A<C>
{
//...
}
But since containerList
should only contain elements of the derived type, you can make it completely generic too like that:
protected List<T> containerList;
and could ommit the OfType()
call:
public Collection<T> ContainerList { get { return new Collection<T>(containerList); }}
One drawback is that someone could have the idea to make a class D
like that:
public class D : A<B>
{}
and would now have a class D
with a ContainerList
of type Collection<B>
. But if it's that what he wants...
Upvotes: 2
Reputation: 152566
Now, I'd like, somehow, to have a base property / method in A which would cast itself to whatever the real type of the object is, i.e. B or C.
I think you're mixing casting and converting. A Cast is a compile-time construct that just determines how methods and properties are bound at compile-time. It does not change the underlying object.
There's no conversion necessary because the object is already either a B
or a C
- since A
is abstract you can't have an object that is actually an A
.
So a method that returns the underlying collection as either a collection of B
s or Cs
would just be:
public IEnumerable<B> GetBs()
{
return containerList.OfType<B>();
}
public IEnumerable<C> GetCs()
{
return containerList.OfType<C>();
}
If you want one generic method where the caller determines the type, you can do:
public IEnumerable<T> GetTs<T>() where T:A
{
return containerList.OfType<T>();
}
Upvotes: 2
Reputation: 467
Instead of casting the objects in the list, you could use the is
keyword (documentation link). When you need to operate on your List, just ask before doing your operation if (containerList[i] is B)
.
Upvotes: 0