Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// So you want to use anonymous interface implementations in C#? Does this lambda-based usage look ok?
// Ignore the fact that "list" and "projection" are undefined here, just note the lambdas that can close
// around any variables and procedures you want.
new AnonymousReadOnlyList<TOut>(
count: () => list.Count,
item: i => projection(list[i]),
iterator: list.AsEnumerable().Select(projection));
new AnonymousReadOnlyList<TOut>(
count: () => list.Count,
item: i => projection(list[i], i),
iterator: list.AsEnumerable().Select(projection));
new AnonymousReadOnlyList<T>(
count: () => list.Count,
item: i => list[list.Count - 1 - i]);
new AnonymousReadOnlyList<TOut>(
count: () => Math.Min(list1.Count, list2.Count),
item: i => projection(list1[i], list2[i]),
iterator: list1.AsEnumerable().Zip(list2, projection));
new AnonymousReadOnlyList<int>(
count: () => count,
item: i => i,
iterator: Enumerable.Range(0, count));
// ... and so on. This is how:
// 1. Define your interface.
public interface IReadOnlyList<out T> : IReadOnlyCollection<T> {
T this[int index] { get; }
}
// 2. Provide a single not-so-concrete implementation for all anonymous implementations to use.
// This also shows how to provide "default methods" - GetEnumerator() here.
public sealed class AnonymousReadOnlyList<T> : IReadOnlyList<T> {
private readonly Func<int> _count;
private readonly Func<int, T> _item;
private readonly IEnumerable<T> _iterator;
public AnonymousReadOnlyList(Func<int> count, Func<int, T> item, IEnumerable<T> iterator = null) {
if (count == null) throw new ArgumentNullException("count");
if (item == null) throw new ArgumentNullException("item");
this._count = count;
this._item = item;
this._iterator = iterator ?? DefaultIterator(count, item);
}
private static IEnumerable<T> DefaultIterator(Func<int> count, Func<int, T> item) {
var n = count();
for (var i = 0; i < n; i++)
yield return item(i);
}
public int Count {
get {
return _count();
}
}
public T this[int index] {
get {
return _item(index);
}
}
public IEnumerator<T> GetEnumerator() {
return _iterator.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
// 3. Now you can create anonymous implementations with lambdas like the ones at the beginning of this gist!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.