I have a class PricingModel with two derived classes: Recurring and Packaged. in my home controller I make the following reference:
View开发者_StackOverflowBag.X = db.PricingModels.Where(x => x.Type == "Packaged").Select(x => x).ToArray();
foreach (var o in ViewBag.X)
{
var xy = o.Discount;
}
which works fine. If I change that to:
var X = db.PricingModels.Where(x => x.Type == "Packaged").Select(x => x).ToArray();
foreach (var o in X)
{
var xy = o.Discount;
}
the reference to o.Discount complains:
Error 2 'Website.Models.PricingModel' does not contain a definition for 'Discount' and no extension method 'Discount' accepting a first argument of type 'Website.Models.PricingModel' could be found (are you missing a using directive or an assembly reference?) C:\Users\ekkis\Documents\Visual Studio 2010\Projects\SkillScore\Website\Controllers\HomeController.cs 46 32 Website
I think that the ViewBag.X[0].Discount works because the ViewBag is untyped... the value's there but the compiler doesn't know about it. My question is: why can't doesn't the compiler see the property of the derived class?
I tried casting it but to no avail:
...ToArray().Cast<Packaged>()
also:
var xy = ((Packaged) o).Discount;
so what am I missing?
I think it would be better to use the OfType extension method instead of Cast.
db.PricingModels.OfType<Packaged>.ToList()
Cast does exactly that - cast, however ofType will actually only return items of type Pacakged. Also, the Select() is not needed as you're trasnforming an object of T to itself.
If I understand your code correctly, it might crash when a type is not a Packaged type.
And yes, the reason it works with the ViewBag is because the ViewBag is a Dynamic, so there is no compile-time checking as everything happens at runtime.
.Cast() won't work for non native types. so I've ended up doing:
List<PricingModel> Packages = db.PricingModels
.Where(x => x.Type == "Packaged")
.ToList();
foreach (Packaged o in Packages) { ... }
which works just fine (finally!)
精彩评论