Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 5846440

Browse files
committed
Merge pull request #2887 from stephentoub/fix_generics_linq
Restore virtual generic usage in LINQ
2 parents ac7a7e8 + 7930a22 commit 5846440

File tree

1 file changed

+7
-41
lines changed

1 file changed

+7
-41
lines changed

src/System.Linq/src/System/Linq/Enumerable.cs

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -118,35 +118,7 @@ public IEnumerator<TSource> GetEnumerator()
118118

119119
public abstract bool MoveNext();
120120

121-
public IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector)
122-
{
123-
// This method is a generic virtual (actually abstract) in the original desktop source.
124-
// Once we have generic virtual's supported in the toolset, we can make this back into an abstract.
125-
//
126-
// This is a workaround implementation that does the "virtual dispatch" manually.
127-
128-
WhereEnumerableIterator<TSource> wei = this as WhereEnumerableIterator<TSource>;
129-
if (wei != null) return wei.SelectImpl<TResult>(selector);
130-
131-
WhereArrayIterator<TSource> wai = this as WhereArrayIterator<TSource>;
132-
if (wai != null) return wai.SelectImpl<TResult>(selector);
133-
134-
WhereListIterator<TSource> wli = this as WhereListIterator<TSource>;
135-
if (wli != null) return wli.SelectImpl<TResult>(selector);
136-
137-
// If we got here, then "this" is one of these types:
138-
//
139-
// WhereSelectEnumerableIterator<TSource, some completely random type>
140-
// WhereSelectArrayIterator<TSource, some completely random type>
141-
// WhereSelectListIterator<TSource, some completely random type>
142-
//
143-
// Normally, this happens when you chain two consecutive Select<,>. There may be
144-
// some clever way to handle that second generic parameter within the limitations of the
145-
// static type system but it's a lot simpler just to break the chain by inserting
146-
// a dummy Where(x => y) in the middle.
147-
//
148-
return new WhereEnumerableIterator<TSource>(this, x => true).SelectImpl<TResult>(selector);
149-
}
121+
public abstract IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector);
150122

151123
public abstract IEnumerable<TSource> Where(Func<TSource, bool> predicate);
152124

@@ -222,8 +194,7 @@ public override bool MoveNext()
222194
return false;
223195
}
224196

225-
// Once we have generic virtual support back, rename this back to Select and turn it into an override of the parent's abstract Select() method.
226-
public IEnumerable<TResult> SelectImpl<TResult>(Func<TSource, TResult> selector)
197+
public override IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector)
227198
{
228199
return new WhereSelectEnumerableIterator<TSource, TResult>(_source, _predicate, selector);
229200
}
@@ -270,8 +241,7 @@ public override bool MoveNext()
270241
return false;
271242
}
272243

273-
// Once we have generic virtual support back, rename this back to Select and turn it into an override of the parent's abstract Select() method.
274-
public IEnumerable<TResult> SelectImpl<TResult>(Func<TSource, TResult> selector)
244+
public override IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector)
275245
{
276246
return new WhereSelectArrayIterator<TSource, TResult>(_source, _predicate, selector);
277247
}
@@ -323,8 +293,7 @@ public override bool MoveNext()
323293
return false;
324294
}
325295

326-
// Once we have generic virtual support back, rename this back to Select and turn it into an override of the parent's abstract Select() method.
327-
public IEnumerable<TResult> SelectImpl<TResult>(Func<TSource, TResult> selector)
296+
public override IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector)
328297
{
329298
return new WhereSelectListIterator<TSource, TResult>(_source, _predicate, selector);
330299
}
@@ -388,8 +357,7 @@ public override bool MoveNext()
388357
return false;
389358
}
390359

391-
// Once we have generic virtual support back, rename this back to Select and turn it into an override of the parent's abstract Select() method.
392-
public IEnumerable<TResult2> SelectImpl<TResult2>(Func<TResult, TResult2> selector)
360+
public override IEnumerable<TResult2> Select<TResult2>(Func<TResult, TResult2> selector)
393361
{
394362
return new WhereSelectEnumerableIterator<TSource, TResult2>(_source, _predicate, CombineSelectors(_selector, selector));
395363
}
@@ -438,8 +406,7 @@ public override bool MoveNext()
438406
return false;
439407
}
440408

441-
// Once we have generic virtual support back, rename this back to Select and turn it into an override of the parent's abstract Select() method.
442-
public IEnumerable<TResult2> SelectImpl<TResult2>(Func<TResult, TResult2> selector)
409+
public override IEnumerable<TResult2> Select<TResult2>(Func<TResult, TResult2> selector)
443410
{
444411
return new WhereSelectArrayIterator<TSource, TResult2>(_source, _predicate, CombineSelectors(_selector, selector));
445412
}
@@ -508,8 +475,7 @@ public override bool MoveNext()
508475
return false;
509476
}
510477

511-
// Once we have generic virtual support back, rename this back to Select and turn it into an override of the parent's abstract Select() method.
512-
public IEnumerable<TResult2> SelectImpl<TResult2>(Func<TResult, TResult2> selector)
478+
public override IEnumerable<TResult2> Select<TResult2>(Func<TResult, TResult2> selector)
513479
{
514480
return new WhereSelectListIterator<TSource, TResult2>(_source, _predicate, CombineSelectors(_selector, selector));
515481
}

0 commit comments

Comments
 (0)