0

I'm doing this.

List<Type1> t1 = ...
List<Type2> t2 = ...
List<Type3> t3 = new List<Type3>();

for(int i = 0; i < t1.Count; i++)
  t3.AddRange(new Type3(t1[i], t2[i]));

I've tried to use foreach by deploying this.

IEnumerable<Type1> t1 = ...
IEnumerable<Type2> t2 = ...
IEnumerable<Object> t12 = t1.Zip(t2, (outer, inner)
  => new{ Outer = outer, Inner = inner});
List<Type3> t3 = new List<Type3>();

foreach(Object element in t12)
  t3.Add(new Type3(element.Outer, element.Inner));

This doesn't fly because Object doesn't recognize the Outer and Inner properties. I can't as it either, because it's a anonymous type. What can I do?

I'd also prefer not to use Object or var but a Tuple or something that says "it's a <Type1,Type2> combo kind of thing".

NB. There's this discussion but that doesn't really answer my question. And in this one I just can't get the fields.

Community
  • 1
  • 1
  • What's so wrong with your first approach? Looks good to me. – Oded Jan 15 '13 at 21:44
  • Tried using var or dynamic? – Mario S Jan 15 '13 at 21:45
  • I'm not exactly clear as to what you are asking. Are you saying that you are currently doing the first? Is that giving you an issue? Why do you want to change it? – cadrell0 Jan 15 '13 at 21:45
  • Why use `Object` as the type of `element`? `Object` doesn't have `Outer` and `Inner` properties. – Oded Jan 15 '13 at 21:46
  • @Oded Because I'm not that good at C# yet. I Went with `Object` because I've create an, well..., object. And the approach is working but I've been told that it's better to use implicit iterators. –  Jan 15 '13 at 21:48
  • @CRMconfusee in this case, using a foreach adds complexity and decreases clarity. Stick with your original implementation. – cadrell0 Jan 15 '13 at 21:52

2 Answers2

4

You should be able to use the anonymous type correctly by using var instead for object in the loop. var infers the type, and allows you to use the anonymous object as expected.

IEnumerable<Type1> t1 = ...
IEnumerable<Type2> t2 = ...
var t12 = t1.Zip(t2, (outer, inner)
  => new{ Outer = outer, Inner = inner});
List<Type3> t3 = new List<Type3>();

foreach(var element in t12)
  t3.Add(new Type3(element.Outer, element.Inner));

If you would like to use Tuple you could do something like this:

IEnumerable<string> t1 = new[] { "test" };
IEnumerable<int> t2 = new[] { 1 };
IEnumerable<Tuple<string, int>> t3 = t1.Zip(t2, (outer, inner) => Tuple.Create(outer, inner));
Xharze
  • 2,703
  • 2
  • 17
  • 30
  • `t12` should also be declared as `var` and not `IEnumerable` – cadrell0 Jan 15 '13 at 21:46
  • Is there a way to say "it's a " without actually creating a class for it? –  Jan 15 '13 at 21:46
  • @CRMconfusee That's an anonymous type. You use `var` with anonymous types. – cadrell0 Jan 15 '13 at 21:51
  • 1
    +1. `Tuple` may be easier to understand if you are very new to anonymous types/C# as you'll be able to explicitly provide type for all variables. – Alexei Levenkov Jan 15 '13 at 22:06
  • @AlexeiLevenkov I like *Tuple* better because it sets more limited bounds on the object returned. I prefer to specify that the *var* is of *Tuple* type, if I can. –  Jan 16 '13 at 12:18
0

Maybe something like this:

IEnumerable<int> t1 = new List<int> { 1, 2, 3 };
IEnumerable<int> t2 = new List<int> { 1, 2, 3 };
var t12 = t1.Zip(t2, (outer, inner) => new { Outer = outer, Inner = inner });
var t3 = t12.Select(t => new { O = t.GetPropValue("Outer"), 
                               I = t.GetPropValue("Inner") });
Phil Boyd
  • 380
  • 3
  • 17