I'm looking at some very interesting code. I am trying to understand why it works.
The code in the controller is as follows.
var paymentInfo = controllerService.GetPaymentSummary();
ViewBag.PaymentInfo = paymentInfo;
In the controller service class there is this code.
public IEnumerable<SomeType> GetPaymentSummary()
{
// ...
return paymentInfo; // is of type List<SomeType>
}
And in the View, there is this very interesting code.
@if (ViewBag.PaymentInfo.Count > 0)
{
// do something..
}
The View makes use of Count
property which belongs to List<T>
. How is this possible?
In the controller, for example, I cannot write paymentInfo.Count
because paymentInfo
is of type IEnumerable<SomeType>
.
I understand that this has something to do with ViewBag
being dynamic, but could someone elaborate please?
(Think of it this way:
IEnumerable
is just a contract, stating certain requirements that the return value from your method (that is paymentInfo
) must have.
What paymentInfo
actually is, is a List
. Since List
implements IEnumerable
, it can also behave as and be treated as an IEnumerable
, but it's runtime type is still List
.
When using Dynamic
, what is important is not the specified return type (IEnumerable
), but the actual object; All that is checked is "does this object contain a member Count
?", and since List
has a Count
, this works out fine.
Of course, if GetPaymentSummary()
should change at some point, and return some other implementation of IEnumerable
that does not contain a Count
member, your code might break.
Updated after feedback in a comment below:
You can avoid that by using .Any()
instead:
@if (ViewBag.PaymentInfo.Any())
{
// do something..
}
This should work fine since .Any()
is declared in IEnumerable
, and not just in List
.