By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,217 Members | 1,443 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,217 IT Pros & Developers. It's quick & easy.

Casting of generics?

P: n/a
Hi all!

I have a problem of casting generics to their base type. In the code
below I first define a BaseList class that can hold items of any type
that inherits from BaseItem. I then define a DerivedList that can hold
items of the type DerivedItem, which inherits from BaseList.
So far so good... But if I somehow get an object that I know is a
subclass of BaseList (and therefor holds subclasses of BaseItem) and
try to cast it to BaseList<BaseItemi get an InvalidCastException
(also below).
Because both the list class and the item class(es) it contains can be
cast to their base classes I think that the whole should also be
castable? Or am I wrong? Is this an syntactic error or a thought fault?
=)

Regards,
Richard

Code (can also be found at http://pastebin.com/866977 )

class BaseItem {
}

class DerivedItem : BaseItem {
}

class BaseList<Twhere T : BaseItem {
}

class DerivedList : BaseList<DerivedItem{
}

class Program {
static void Main(string[] args) {
// Suppose i get this value (dl) from outside as an object.
// I only know that it is a subclass of BaseList and it is
// parameterized with some subclass of BaseItem
DerivedList dl = new DerivedList();
object o = dl;

// This cast fails!
BaseList<BaseItemdl2 = (BaseList<BaseItem>) o;
}
}

Exception:

System.InvalidCastException was unhandled
Message="Unable to cast object of type 'TestConsoleApp.DerivedList'
to type 'TestConsoleApp.BaseList`1[TestConsoleApp.BaseItem]'."
Source="TestConsoleApp"
StackTrace:
at TestConsoleApp.Program.Main(String[] args) in Program.cs:line
28
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[]
args)
at System.AppDomain.ExecuteAssembly(String assemblyFile,
Evidence assemblySecurity, String[] args)
at
Microsoft.VisualStudio.HostingProcess.HostProc.Run UsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context( Object
state)
at System.Threading.ExecutionContext.Run(ExecutionCon text
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

Jan 25 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
You can't, I remembered a post on the same(ish, it's the same concept)
topic a while ago which can be found here (Watch wrap)--->

http://groups.google.co.uk/group/mic...77888d00f45e93

On 25 Jan, 13:25, "psyCK0" <nasseg...@gmail.comwrote:
Hi all!

I have a problem of casting generics to their base type. In the code
below I first define a BaseList class that can hold items of any type
that inherits from BaseItem. I then define a DerivedList that can hold
items of the type DerivedItem, which inherits from BaseList.
So far so good... But if I somehow get an object that I know is a
subclass of BaseList (and therefor holds subclasses of BaseItem) and
try to cast it to BaseList<BaseItemi get an InvalidCastException
(also below).
Because both the list class and the item class(es) it contains can be
cast to their base classes I think that the whole should also be
castable? Or am I wrong? Is this an syntactic error or a thought fault?
=)

Regards,
Richard

Code (can also be found athttp://pastebin.com/866977)

class BaseItem {

}class DerivedItem : BaseItem {

}class BaseList<Twhere T : BaseItem {

}class DerivedList : BaseList<DerivedItem{

}class Program {
static void Main(string[] args) {
// Suppose i get this value (dl) from outside as an object.
// I only know that it is a subclass of BaseList and it is
// parameterized with some subclass of BaseItem
DerivedList dl = new DerivedList();
object o = dl;

// This cast fails!
BaseList<BaseItemdl2 = (BaseList<BaseItem>) o;
}

}Exception:

System.InvalidCastException was unhandled
Message="Unable to cast object of type 'TestConsoleApp.DerivedList'
to type 'TestConsoleApp.BaseList`1[TestConsoleApp.BaseItem]'."
Source="TestConsoleApp"
StackTrace:
at TestConsoleApp.Program.Main(String[] args) in Program.cs:line
28
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[]
args)
at System.AppDomain.ExecuteAssembly(String assemblyFile,
Evidence assemblySecurity, String[] args)
at
Microsoft.VisualStudio.HostingProcess.HostProc.Run UsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context( Object
state)
at System.Threading.ExecutionContext.Run(ExecutionCon text
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Jan 25 '07 #2

P: n/a
Remember that Generics allow you to create strong data types, and treat them
as such. So,

DerivedList : BaseList<DerivedItem>

is a strongly-typed BaseList, of type DerivedItem.

However, you are attempting to cast it to:

BaseList<BaseItem>

which is a strongly-typed BaseList of type BaseItem.

Now, if you were to cast it as

BaseList<DerivedItem>

which is the type it inherits, the cast would not fail.
BaseList<DerivedItemdoes not inherit BaseList<BaseItem>.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

The shortest distance between 2 points is a curve.
"psyCK0" <na*******@gmail.comwrote in message
news:11*********************@q2g2000cwa.googlegrou ps.com...
Hi all!

I have a problem of casting generics to their base type. In the code
below I first define a BaseList class that can hold items of any type
that inherits from BaseItem. I then define a DerivedList that can hold
items of the type DerivedItem, which inherits from BaseList.
So far so good... But if I somehow get an object that I know is a
subclass of BaseList (and therefor holds subclasses of BaseItem) and
try to cast it to BaseList<BaseItemi get an InvalidCastException
(also below).
Because both the list class and the item class(es) it contains can be
cast to their base classes I think that the whole should also be
castable? Or am I wrong? Is this an syntactic error or a thought fault?
=)

Regards,
Richard

Code (can also be found at http://pastebin.com/866977 )

class BaseItem {
}

class DerivedItem : BaseItem {
}

class BaseList<Twhere T : BaseItem {
}

class DerivedList : BaseList<DerivedItem{
}

class Program {
static void Main(string[] args) {
// Suppose i get this value (dl) from outside as an object.
// I only know that it is a subclass of BaseList and it is
// parameterized with some subclass of BaseItem
DerivedList dl = new DerivedList();
object o = dl;

// This cast fails!
BaseList<BaseItemdl2 = (BaseList<BaseItem>) o;
}
}

Exception:

System.InvalidCastException was unhandled
Message="Unable to cast object of type 'TestConsoleApp.DerivedList'
to type 'TestConsoleApp.BaseList`1[TestConsoleApp.BaseItem]'."
Source="TestConsoleApp"
StackTrace:
at TestConsoleApp.Program.Main(String[] args) in Program.cs:line
28
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[]
args)
at System.AppDomain.ExecuteAssembly(String assemblyFile,
Evidence assemblySecurity, String[] args)
at
Microsoft.VisualStudio.HostingProcess.HostProc.Run UsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context( Object
state)
at System.Threading.ExecutionContext.Run(ExecutionCon text
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

Jan 25 '07 #3

P: n/a


On Jan 25, 5:25 am, "psyCK0" <nasseg...@gmail.comwrote:
Hi all!

I have a problem of casting generics to their base type. In the code
below I first define a BaseList class that can hold items of any type
that inherits from BaseItem. I then define a DerivedList that can hold
items of the type DerivedItem, which inherits from BaseList.
So far so good... But if I somehow get an object that I know is a
subclass of BaseList (and therefor holds subclasses of BaseItem) and
try to cast it to BaseList<BaseItemi get an InvalidCastException
(also below).
Because both the list class and the item class(es) it contains can be
cast to their base classes I think that the whole should also be
castable? Or am I wrong? Is this an syntactic error or a thought fault?
=)
It's a "thought fault". Think about it for a moment: if you could cast
a BaseList<DerivedItemto a reference variable for a
BaseList<BaseItem>, then you could add BaseItems to the list, which
clearly violates the constraint that the list is of DerivedItems. For
example:

BaseList<FiremanfireList = new BaseList<Fireman>();
BaseList<PersonpersonList = (BaseList<Person>)fireList;
personList.Add(new ComputerProgrammer());

If the second line were allowed, then the third line could not be
checked at compile time, which would incur a run-time cost (type
checking) for all operations on generics, which is precisely what
generics seek to avoid.

Generics make strong guarantees that can be verified at compile time,
and so need no run-time type checking.

Jan 25 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.