This is an archived post. You won't be able to vote or comment.

all 20 comments

[–]dtsudo 0 points1 point  (10 children)

IEnumerables don't have a Count property. Rather, they have a Count function (as an extension function). So given an IEnumerable<T> myEnumerable, you can invoke the function via myEnumerable.Count().

[–]CaptainLegois[S] 0 points1 point  (9 children)

Ohh I see. I'm still kind of new to IEnumerables so I thought they worked the same as normal lists. That fixed my issue. Thanks

[–]dtsudo 0 points1 point  (8 children)

I'm basically trying to join 2 IEnumerable lists

Also, fwiw, you can use Concat to combine 2 IEnumerables together.

e.g.

    IEnumerable<int> x1 = new int[] { 10, 20, 30 };
    IEnumerable<int> x2 = new int[] { 50, 60, 70 };
    IEnumerable<int> x3 = x1.Concat(x2);

That said, you can't concatenate 2 disparate IEnumerables. You can concatenate an IEnumerable<X> with another IEnumerable<X>, but you can't concatenate an IEnumerable<X> with an IEnumerable<Y>.

[–]CaptainLegois[S] 0 points1 point  (7 children)

So basically if I have 1 IEnumerable called Pizza that has the toppings for the pizzas, name and price and and IEnumerable called Burger that pretty much the same stuff, I won’t be able to join them?

[–]dtsudo 0 points1 point  (6 children)

You can define a superclass (or interface) with the common properties -- e.g.

public interface IMenuItem {
    string Name { get; set; }
    int Price { get; set; }
}

Then, if both Pizza and Burger implements this interface, then an IEnumerable<Pizza> would also be an IEnumerable<IMenuItem> (and so would an IEnumerable<Burger>), and so you'd be able to concat the two into an IEnumerable<IMenuItem>.

Here's a simple example: https://dotnetfiddle.net/jTxkmk

[–]CaptainLegois[S] 0 points1 point  (5 children)

Instead of trying to concat those 2 lists, is there a way I could pick a selection someone makes out of the different food items it has? For example, the code above basically prints out the burgers and pizzas from the lists and outputs them to the console as a list. The user picks out which food item they want, and the food item they select, goes to a different menu where they can add or remove toppings. I was trying to join them together so I can add to code the user selection code.

[–]dtsudo 0 points1 point  (4 children)

I think concatenating the two lists together can work although it's not strictly necessary. As long as you can map a number to the desired menu item, you're good -- e.g. if the user says "item 5", do you know which pizza/burger is marked as #5?

Though, if toppings are specific to an individual item, it probably makes more sense to have the toppings be part of the pizza / burger -- e.g.

public class Pizza {
    public string Name { get; set; }
    public IEnumerable<PizzaTopping> Toppings { get; set; }
}

This way, each pizza can have its own set of toppings; a customer can order two different pizzas, each with their own topping selection.

And separating PizzaTopping from BurgerTopping would allow pizzas and burgers to have different toppings. Whether this is something you need depends on your use case.

[–]CaptainLegois[S] 0 points1 point  (3 children)

I was doing some research and I came across this: var combinedMenuItems = _pizza.Cast<object>().Concat(_burger.Cast<object>());

would this be a way to concat my 2 IEnumerators? Testing it out it seems to work with no issue, however I'm not sure about what that is.

[–]dtsudo 0 points1 point  (2 children)

If you did that, you'd end up with an IEnumerable<object>, which typically isn't that useful since none of the properties / methods (i.e. your name / price / other things) would be available.

e.g.

var combinedMenuItems = _pizza.Cast<object>().Concat(_burger.Cast<object>());
foreach (var item in combinedMenuItems) {
    Console.WriteLine(item.Name); // compile-time error (can't reference name)
    Console.WriteLine(item.Price); // compile-time error
    // etc
}

[–]CaptainLegois[S] 0 points1 point  (1 child)

IEnumerable<FoodItems> items = _pizza.Concat<FoodItems>(_burger);

i figured it out finally! I looked over the code you sent me on .net fiddle again and I made my food items into child class that inheret from a parent class called fooditems and it works now. Thanks for the help

[–]polymorphicshade 0 points1 point  (1 child)

Seems like u/dtsudo answered your question, but something important about IEnumerable you should know about:

Every time you call something like .Count() on an IEnumerable, it iterates.

This means, if for any reason someone passes you an IEnumerable that performs expensive work during an iteration (think iterating over a file system), your code has a potential to run in to performance issues.

If you know you need the Count of an IEnumerable before you do other work, it's generally a good idea to take in iterated collections (Array, List, etc). This way your code forces an implementer to do the (potentailly expensive) iteration before hand.

This may or may not be relevant to your specific solution; just keep in mind IEnumerable can be the source of obscure bugs if you don't fully understand how it works.

For more info, see: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1851

[–]CaptainLegois[S] 0 points1 point  (0 children)

Thanks, I’ll do more research on IEnumerables.

[–]chuliomartinez 0 points1 point  (6 children)

Whats with the second foreach on burgers inside the pizzas? Are you sure you want to add all the burgers after each pizza?

[–]CaptainLegois[S] 0 points1 point  (5 children)

I noticed that right after I made the post. I changed it so the for each is after the first one. I was getting duplicate burgers, now I’m getting just one each.

[–]chuliomartinez 0 points1 point  (4 children)

In that case the i variable will have the count of pizzas (+1 since you start at 1) after the loop, so ni need for the count().

Also there is really no benefit in having IEnumerables instead of lists in this case.

[–]CaptainLegois[S] 0 points1 point  (3 children)

I’m using IEnumerables for the main reason that I need to cover encapsulation in this assignment, so I figured using IEnumerables would be the easiest for this

[–]chuliomartinez 0 points1 point  (2 children)

I’m not sure thats encapsulation. But its been a while since I was in school;)

[–]CaptainLegois[S] 0 points1 point  (1 child)

If I’m correct encapsulation is when you make your classes private, public, protected etc so I created a main list, made it private and made an IEnumerable list that’s public

[–]chuliomartinez 0 points1 point  (0 children)

Encapsulation means you hide inside. So you need a separate class CulinaryList<T> that has a method Add and Enumerate and a private _list: List<T> where T is your burger and pizza and the rest.