Generics: T not assignable to known type. (Why wont this compile?)
I've recently tried to simplify some of my code by using generics where possible. However, this particular example has me stumped... Yet it looks so innocent!
Here's the offending code (simplified).
public static void Updater(CommodityVO vo)
{
// Update something
}
public static void BulkUpdate<T>(IEnumerable<T> vos)
{
foreach (var vo in vos)
{
Updater(vo);
}
}
In Visual Studio, the 'vo' in 'Updater(vo)' get开发者_JAVA技巧s a squiggly line and the compiler (VS2010) reports:
Argument type 'T' is not assignable to parameter type CommodityVO
<T
> behaves the same as IEnumerable<T
>I have worked around this issue for now. But I'd like to know why this was rejected... Especially since it all looks fine to me. What am I missing?
All help appreciated.
What you're looking for here is a generic constraint. The type T
needs to be constrained to be an instance of CommodityVO
public static void BulkUpdate<T>(IEnumerable<T> vos) where T : CommodityVO {
foreach (var vo in vos) {
Updater(vo);
}
}
Without this generic constraint the C# compiler has no information on the generic parameter T
and must assume the worst case that T
is instantiated as object
. The type object
is not compatible with CommodityVO
and hence it issues an error. By adding the constraint you are limiting the values T
can be instantiated as to CommodityVO
or types deriving from CommodityVO
which means the conversion to CommodityVO
is legal and hence allowed.
The Updater function can only handle objects of type CommodityVO
.
If this is a base type of various types you want to be able to pass to Updater, add a where constraint. where T : CommodityVO
This should work
public static void BulkUpdate<T>(IEnumerable<T> vos) where T : CommodityVO
{
foreach (var vo in vos)
{
Updater(vo);
}
}
You want to constrain the generic type T to a type your Updater function actually accepts.
精彩评论