There are several pattern-features of C# language, i.e. classes need not derive from a specific interface; but rather implement a certain pattern in order to partake in some C# syntax/features.
Let's consider an example:
public class MyCollection : IEnumerable
{
public T Add(T name, T name2, ...) { }
public IEnumerator GetEnumerator() { return null; }
}
Here, TYPE is any type. Basically we have a class that implements IEnumerable and has a method named Add() with any number of parameters.
This enables the following declaration of a new MyCollection instance:
new MyCollection{{a1, a2, ...}, {b1, b2, ...} }
Which is equivalent to:
var mc = new MyCollection();
mc.Add(a1, a1, ...);
mc.Add(b1, b2, ...);
Magic! Meanwhile, recently (I believe during the BUILD event) Anders Hejlsberg let slip that the new await/async will be implemented using patterns as well, which lets WinRT get away with returning something other than Task<T>.
So my question is twofold,
What is the pattern Anders was talking about, or did I misunderstand something? The answer should be somewhere between the type WinRT provides, something to the effect of IAsyncFoo and the unpublished specification.
Are there any other such patterns (perhaps already existing) in C#?
The draft specification is published - you can download it from the Visual Studio home page. The pattern for async is the one given in driis's answer - you can also read my Eduasync blog series for more details, with this post being dedicated to the pattern.
Note that this pattern only applies to "what you can await". An async method must return void, Task or Task<T>.
In terms of other patterns in C# beyond the collection initializer you mentioned originally:
foreach can iterate over non-IEnumerable implemenations, so long as the type has a GetEnumerator method returning a type which has MoveNext() and Current members
LINQ query expressions resolve to calls to Select, Where, GroupBy etc.
For async, it works on the awaiter pattern, which I think is described best here, by Stephen Toub:
"The languages support awaiting any instance that exposes the right method (either instance method or extension method): GetAwaiter. A GetAwaiter needs to return a type that itself exposes three members:"
bool IsCompleted { get; }
void OnCompleted(Action continuation);
TResult GetResult(); // TResult can also be void
As an example of this, in the Async CTP, Task’s GetAwaiter method returns a value of type TaskAwaiter:
public struct TaskAwaiter
{
public bool IsCompleted { get; }
public void OnCompleted(Action continuation);
public void GetResult();
}
If you want all the details of async, start reading Jon Skeets posts about async. They go into great detail about the subject.
Besides collection initializers, which is pattern based as you mention, another pattern based feature in C# is LINQ: For the LINQ keywords, all that is required is that overload resolution finds an instance or extension method with the correct name and signature. Have a look at Eric Lipperts article about the subject. Also, foreach is pattern based - Eric also describes the details on this pattern in the linked article.
Another pattern you can use is the using keyword.
If you have a class that implements IDisposable then you can say:
using(Resource myResource = GetResource())
{
}
Which translates to something akin to::
Resource myResource;
try
{
myResource = GetResource();
}
finally
{
var disposable = myResource as IDisposable;
if(disposable != null) disposable.Dispose()
}
While I suppose it is less "magical" than foreach or the query operators it is a relatively nice bit of syntax.
Also a bit more in the same vein you can use the yield return to automatically implement an iterator for you.
public struct SimpleBitVector32 : IEnumerable<bool>
{
public SimpleBitVector32(uint value)
{
this.data = value;
}
private uint data;
public bool this[int offset]
{
get
{
unchecked
{
return (this.data & (1u << offset)) != 0;
}
}
set
{
unchecked
{
this.data = value ? (this.data | (1u << offset)) : (this.data & ~(1u << offset));
}
}
}
public IEnumerator<bool> GetEnumerator()
{
for (int i = 0; i < 32; i++)
{
yield return this[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Related
(Sorry for the vague title; couldn't think of anything better. Feel free to rephrase.)
So let's say my function or property returns an IEnumerable<T>:
public IEnumerable<Person> Adults
{
get
{
return _Members.Where(i => i.Age >= 18);
}
}
If I run a foreach on this property without actually materializing the returned enumerable:
foreach(var Adult in Adults)
{
//...
}
Is there a rule that governs whether IEnumerable<Person> will be materialized to array or list or something else?
Also is it safe to cast Adults to List<Person> or Array without calling ToList() or ToArray()?
Edit
Many people have spent a lot of effort into answering this question. Thanks to all of them. However, the gist of this question still remains unanswered. Let me put in some more details:
I understand that foreach doesn't require the target object to be an array or list. It doesn't even need to be a collection of any kind. All it needs the target object to do is to implement enumeration. However if I place inspect the value of target object, it reveals that the actual underlying object is List<T> (just like it shows object (string) when you inspect a boxed string object). This is where the confusion starts. Who performed this materialization? I inspected the underlying layers (Where() function's source) and it doesn't look like those functions are doing this.
So my problem lies at two levels.
First one is purely theoretical. Unlike many other disciplines like physics and biology, in computer sciences we always know precisely how something works (answering #zzxyz's last comment); so I was trying to dig about the agent who created List<T> and how it decided it should choose a List and not an Array and if there is a way of influencing that decision from our code.
My second reason was practical. Can I rely on the type of actual underlying object and cast it to List<T>? I need to use some List<T> functionality and I was wondering if for example ((List<Person>)Adults).BinarySearch() is as safe as Adults.ToList().BinarySearch()?
I also understand that it isn't going to create any performance penalty even if I do call ToList() explicitly. I was just trying to understand how it is working. Anyway, thanks again for the time; I guess I have spent just too much time on it.
In general terms all you need for a foreach to work is to have an object with an accessible GetEnumerator() method that returns an object that has the following methods:
void Reset()
bool MoveNext()
T Current { get; private set; } // where `T` is some type.
You don't even need an IEnumerable or IEnumerable<T>.
This code works as the compiler figures out everything it needs:
void Main()
{
foreach (var adult in new Adults())
{
Console.WriteLine(adult.ToString());
}
}
public class Adult
{
public override string ToString() => "Adult!";
}
public class Adults
{
public class Enumerator
{
public Adult Current { get; private set; }
public bool MoveNext()
{
if (this.Current == null)
{
this.Current = new Adult();
return true;
}
this.Current = null;
return false;
}
public void Reset() { this.Current = null; }
}
public Enumerator GetEnumerator() { return new Enumerator(); }
}
Having a proper enumerable makes the process work more easily and more robustly. The more idiomatic version of the above code is:
public class Adults
{
private class Enumerator : IEnumerator<Adult>
{
public Adult Current { get; private set; }
object IEnumerator.Current => this.Current;
public void Dispose() { }
public bool MoveNext()
{
if (this.Current == null)
{
this.Current = new Adult();
return true;
}
this.Current = null;
return false;
}
public void Reset()
{
this.Current = null;
}
}
public IEnumerator<Adult> GetEnumerator()
{
return new Enumerator();
}
}
This enables the Enumerator to be a private class, i.e. private class Enumerator. The interface then does all of the hard work - it's not even possible to get a reference to the Enumerator class outside of Adults.
The point is that you do not know at compile-time what the concrete type of the class is - and if you did you may not even be able to cast to it.
The interface is all you need, and even that isn't strictly true if you consider my first example.
If you want a List<Adult> or an Adult[] you must call .ToList() or .ToArray() respectively.
There is no such thing as a default concrete type for any interface.
The entire point of an interface is to guarantee properties, methods, events or indexers, without the user need of any knowledge of the concrete type that implements it.
When using an interface, all you can know is the properties, methods, events and indexers this interface declares, and that's all you actually need to know. That's just another aspect of encapsulation - same as when you are using a method of a class you don't need to know the internal implementation of that method.
To answer your question in the comments:
who decides that concrete type in case we don't, just as I did above?
That's the code that created the instance that's implementing the interface.
Since you can't do var Adults = new IEnumerable<Person> - it has to be a concrete type of some sort.
As far as I see in the source code for linq's Enumerable extensions - the where returns either an instance of Iterator<TSource> or an instance of WhereEnumerableIterator<TSource>. I didn't bother checking further what exactly are those types, but I can pretty much guarantee they both implement IEnumerable, or the guys at Microsoft are using a different c# compiler then the rest of us... :-)
The following code hopefully highlights why neither you nor the compiler can assume an underlying collection:
public class OneThroughTen : IEnumerable<int>
{
private static int bar = 0;
public IEnumerator<int> GetEnumerator()
{
while (true)
{
yield return ++bar;
if (bar == 10)
{ yield break; }
}
}
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
class Program
{
static void Main(string[] args)
{
IEnumerable<int> x = new OneThroughTen();
foreach (int i in x)
{ Console.Write("{0} ", i); }
}
}
Output being, of course:
1 2 3 4 5 6 7 8 9 10
Note, the code above behaves extremely poorly in the debugger. I don't know why. This code behaves just fine:
public IEnumerator<int> GetEnumerator()
{
while (bar < 10)
{
yield return ++bar;
}
bar = 0;
}
(I used static for bar to highlight that not only does the OneThroughTen not have a specific collection, it doesn't have any collection, and in fact has no instance data whatsoever. We could just as easily return 10 random numbers, which would've been a better example, now that I think on it :))
From your edited question and comments it sounds like you understand the general concept of using IEnumerable, and that you cannot assume that "a list object backs all IEnumerable objects". Your real question is about something that has confused you in the debugger, but we've not really been able to understand exactly what it is you are seeing. Perhaps a screenshot would help?
Here I have 5 IEnumerable<int> variables which I assign in various ways, along with how the "Watch" window describes them. Does this show the confusion you are having? If not, can you construct a similarly short program and screenshot that does?
Coming a bit late into the party here :)
Actually Linq's "Where" decides what's going to be the underlying implementation of IEnumerable's GetEnumerator.
Look at the source code:
https://github.com/dotnet/runtime/blob/918e6a9a278bc66fb191c43d4db4a71e63ffad31/src/libraries/System.Linq/src/System/Linq/Where.cs#L59
You'll see that based on the "source" type, the methods return "WhereSelectArrayIterator" or "WhereSelectListIterator" or a more generic "WhereSelectEnumerableSelector".
Each of this objects implement the GetEnumerator over an Array, or a List, so I'm pretty sure that's why you see the underlying object type being one of these on VS inspector.
Hope this helps clarifying.
I have been digging into this myself. I believe the 'underlying type' is an iterator method, not an actual data structure type.
An iterator method defines how to generate the objects in a sequence
when requested.
https://learn.microsoft.com/en-us/dotnet/csharp/iterators#enumeration-sources-with-iterator-methods
In my usecase/testing, the iterator is System.Linq.Enumerable.SelectManySingleSelectorIterator. I don't think this is a collection data type. It is a method that can enumerate IEnumerables.
Here is a snippet:
public IEnumerable<Item> ItemsToBuy { get; set; }
...
ItemsToBuy = Enumerable.Range(1, rng.Next(1, 20))
.Select(RandomItem(rng, market))
.SelectMany(e => e);
The property is IEnumerable and .SelectMany returns IEnumerable. So what is the actual collection data structure? I don't think there is one in how I am interpreting 'collection data structure'.
Also is it safe to cast Adults to List or Array without
calling ToList() or ToArray()?
Not for me. When attempting to cast ItemsToBuy collection in a foreach loop I get the following runtime exception:
{"Unable to cast object of type
'SelectManySingleSelectorIterator2[System.Collections.Generic.IEnumerable1[CashMart.Models.Item],CashMart.Models.Item]'
to type 'CashMart.Models.Item[]'."}
So I could not cast, but I could .ToArray(). I do suspect there is a performance hit as I would think that the IEnumerable would have to 'do things' to make it an array, including memory allocation for the array even if the entities are already in memory.
However if I place inspect the value of target object, it reveals that
the actual underlying object is List
This was not my experience and I think it may depend on the IEnumerable source as well as the LinQ provider. If I add a where, the returned iterator is:
System.Linq.Enumerable.WhereEnumerableIterator
I am unsure what your _Member source is, but using LinQ-to-Objects, I get an iterator. LinQ-to-Entities must call the database and store the result set in memory somehow and then enumerate on that result. I would doubt that it internally makes it a List, but I don't know much. I suspect instead that _Members may be a List somewhere else in your code thus, even after the .Where, it shows as a List.
I'm writing a Linked List program in C# because I want to test how I feel about the language and I'm running into some serious difficulty. I'm trying to implement a Map method that functions like a Haskell map function (code below for both). However, I'm getting the error messages:
main.cs(43,66): error CS0029: Cannot implicitly convert type `void' to `MainClass.LinkedList<U>'
main.cs(43,33): error CS1662: Cannot convert `lambda expression' to delegate type `System.Func<MainClass.LinkedList<U>>' because some of the return types in the block are not implicitly convertible to the delegate return type
The relevant code in question:
Ideal Haskell code:
map :: [a] -> (a -> b) -> [b]
map (x:[]) f = (f x) : []
map (x:xs) f = (f x) : (map xs f)
C# code:
public class LinkedList<T> where T: class
{
public T first;
public LinkedList<T> rest;
public LinkedList(T x) {this.first = x;}
public void Join(LinkedList<T> xs)
{
Do(this.rest, ()=>this.rest.Join(xs), ()=>Assign(ref this.rest, xs));
}
public LinkedList<U> Map<U>(Func<T, U> f) where U: class
{
return DoR(this.rest, ()=>new LinkedList<U>(f(this.first)).Join(this.rest.Map(f)), ()=>new LinkedList<U>(f(this.first)));
}
public static void Assign<T>(ref T a, T b)
{
a = b;
}
public static U DoR<T, U>(T x, Func<U> f, Func<U> g)
{
if (x!=null) {return f();}
else {return g();}
}
public static void Do<T>(T x, Action f, Action g)
{
if (x != null) {f();}
else {g();}
}
While Assign, DoR (short for Do and Return), and Do seem like they're "code smell", they're what I came up with for trying to not write
if (x != null) {f();}
else {g();}
type statements (I'm used to patternmatching). If anybody has any better ideas, I'd love to know them, but mostly I'm concerned with the highlighted problem.
Starting with your immediate problem: the basic issue here is that you're mixing and matching lambda expressions that have either void return type or an actual return type. This can be addressed by changing your Join() method so that it returns the list used to call Join():
public LinkedList<T> Join(LinkedList<T> xs)
{
Do(this.rest, () => this.rest.Join(xs), () => Assign(ref this.rest, xs));
return this;
}
An alternative way would be to have a statement body lambda in the Map<U>() method that saves the new list to a variable and then returns that. But that adds a lot more code than just changing the Join() method, so it seems less preferable.
That said, you seem to be abusing C# a bit here. Just as when writing code in a functional language, one should really make an effort to write real functional code, in the manner idiomatic to that language, so too should one make an effort when writing C# code to write real imperative code, in the manner idiomatic to C#.
Yes, C# has some functional-like features in it, but they don't generally have the same power as the features found in real functional languages, and they are intended to allow C# programmers to get the low-hanging fruit of functional styles of code without having to switch languages. One particular thing also to be aware of is that lambda expressions generate a lot more code than normal C# imperative code.
Sticking to more idiomatic C# code, the data structure you're implementing above can be written much more concisely, and in a manner that creates much more efficient code. That would look something like this:
class LinkedList<T>
{
public T first;
public LinkedList<T> rest;
public LinkedList(T x) { first = x; }
public void Join(LinkedList<T> xs)
{
if (rest != null) rest.Join(xs);
else rest = xs;
}
public LinkedList<U> Map<U>(Func<T, U> f) where U : class
{
LinkedList<U> result = new LinkedList<U>(f(first));
if (rest != null) result.Join(rest.Map(f));
return result;
}
}
(For what it's worth, I don't see the point of the generic type constraint on your Map<U>() method. Why restrict it like that?)
Now, all that said, it seems to me that if you do want a functional-style linked-list implementation in C#, it would make sense to make it an immutable list. I'm not familiar with Haskell, but from my limited use of functional languages generally, I have the impression that immutability is a common feature in functional language data types, if not enforced 100% (e.g. XSL). So if trying to reimplement functional language constructs in C#, why not follow that paradigm?
See, for example, Eric Lippert's answer in Efficient implementation of immutable (double) LinkedList. Or his excellent series of articles on immutability in C# (you can start here: Immutability in C# Part One: Kinds of Immutability), where you can get ideas for how to create various immutable collection types.
In browsing Stack Overflow for related posts, I found several that, while not directly applicable to your question, may still be of interest (I know I found them very interesting):
how can I create a truly immutable doubly linked list in C#?
Immutable or not immutable?
Doubly Linked List in a Purely Functional Programming Language
Why does the same algorithm work in Scala much slower than in C#? And how to make it faster?
Converting C# code to F# (if statement)
I like that last one mainly for the way that in both the presentation of the question itself and the replies (answers and comments) help illustrate well why it's so important to avoid trying to just transliterate from one language to another, and instead to really try to become familiar with the way a language is designed to be used, and how common data structures and algorithms are represented in a given language, idiomatically.
Addendum:
Inspired by Eric Lippert's rough draft of an immutable list type, I wrote a different version that includes the Join() method, as well as the ability to add elements at the front and end of the list:
abstract class ImmutableList<T> : IEnumerable<T>
{
public static readonly ImmutableList<T> Empty = new EmptyList();
public abstract IEnumerator<T> GetEnumerator();
public abstract ImmutableList<T> AddLast(T t);
public abstract ImmutableList<T> InsertFirst(T t);
public ImmutableList<T> Join(ImmutableList<T> tail)
{
return new List(this, tail);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
class EmptyList : ImmutableList<T>
{
public override ImmutableList<T> AddLast(T t)
{
return new LeafList(t);
}
public override IEnumerator<T> GetEnumerator()
{
yield break;
}
public override ImmutableList<T> InsertFirst(T t)
{
return AddLast(t);
}
}
abstract class NonEmptyList : ImmutableList<T>
{
public override ImmutableList<T> AddLast(T t)
{
return new List(this, new LeafList(t));
}
public override ImmutableList<T> InsertFirst(T t)
{
return new List(new LeafList(t), this);
}
}
class LeafList : NonEmptyList
{
private readonly T _value;
public LeafList(T t)
{
_value = t;
}
public override IEnumerator<T> GetEnumerator()
{
yield return _value;
}
}
class List : NonEmptyList
{
private readonly ImmutableList<T> _head;
private readonly ImmutableList<T> _tail;
public List(ImmutableList<T> head, ImmutableList<T> tail)
{
_head = head;
_tail = tail;
}
public override IEnumerator<T> GetEnumerator()
{
return _head.Concat(_tail).GetEnumerator();
}
}
}
The public API is a little different from Eric's. You enumerate it to access the elements. The implementation is different as well; using a binary tree was how I enabled the Join() method.
Note that with the interface IEnumerable<T> implemented, one way to implement the Map<U>() method is to not do it at all and instead just use the built-in Enumerable.Select():
ImmutableList<T> list = ...; // whatever your list is
Func<T, U> map = ...; // whatever your projection is
IEnumerable<U> mapped = list.Select(map);
As long as the map function is relatively inexpensive, that would work fine. Any time mapped is enumerated, it will re-enumerate list, applying the map function. The mapped enumeration remains immutable, because it's based on the immutable list object.
There are probably other ways to do it (for that matter, I know of at least one other), but the above is what made the most sense to be conceptually.
I'm trying to implement the Iterator pattern.
Basically, from what I understand, it makes a class "foreachble" and makes the code more secure by not revealing the exact collection type to the user.
I have been experimenting a bit and I found out that if I implement
IEnumerator GetEnumerator() in my class, I get the desired result ... seemingly sparing the headache of messing around with realizing interfaces.
Here is a glimpse to what I mean:
public class ListUserLoggedIn
{
/*
stuff
*/
public List<UserLoggedIn> UserList { get; set; }
public IEnumerator<UserLoggedIn> GetEnumerator()
{
foreach (UserLoggedIn user in this.UserList)
{
yield return user;
}
}
public void traverse()
{
foreach (var item in ListUserLoggedIn.Instance)
{
Console.Write(item.Id);
}
}
}
I guess my question is, is this a valid example of Iterator?
If yes, why is this working, and what can I do to make the iterator return only a part or an anonymous object via "var".
If not, what is the correct way ...
First a smaller and simplified self-contained version:
class Program
{
public IEnumerator<int> GetEnumerator() // IEnumerable<int> works too.
{
for (int i = 0; i < 5; i++)
yield return i;
}
static void Main(string[] args)
{
var p = new Program();
foreach (int x in p)
{
Console.WriteLine(x);
}
}
}
And the 'strange' thing here is that class Program does not implement IEnumerable.
The specs from Ecma-334 say:
§ 8.18 Iterators
The foreach statement is used to iterate over the elements of an enumerable collection. In order to be enumerable, a collection shall have a parameterless GetEnumerator method that returns an enumerator.
So that's why foreach() works on your class. No mention of IEnumerable. But how does the GetEnumerator() produce something that implements Current and MoveNext ? From the same section:
An iterator is a statement block that yields an ordered sequence of values. An iterator is distinguished from a normal statement block by the presence of one or more yield statements
It is important to understand that an iterator is not a kind of member, but is a means of implementing a function member
So the body of your method is an iterator-block, the compiler checks a number of constraints (the method must return an IEnumerable or IEnumerator) and then implements the IEnumerator members for you.
And to the deeper "why", I just learned something too. Based on an annotation by Eric Lippert in "The C# Programming Language 3rd", page 369:
This is called the "pattern-based approach" and it dates from before generics. An interface based approach in C#1 would have been totally based on passing object around and value types would always have had to be boxed. The pattern approach allows
foreach (int x in myIntCollection)
without generics and without boxing. Neat.
Ok, as I was poking around with building a custom enumerator, I had noticed this behavior that concerns the yield
Say you have something like this:
public class EnumeratorExample
{
public static IEnumerable<int> GetSource(int startPoint)
{
int[] values = new int[]{1,2,3,4,5,6,7};
Contract.Invariant(startPoint < values.Length);
bool keepSearching = true;
int index = startPoint;
while(keepSearching)
{
yield return values[index];
//The mind reels here
index ++
keepSearching = index < values.Length;
}
}
}
What makes it possible underneath the compiler's hood to execute the index ++ and the rest of the code in the while loop after you technically do a return from the function?
The compiler rewrites the code into a state machine. The single method you wrote is split up into different parts. Each time you call MoveNext (either implicity or explicitly) the state is advanced and the correct block of code is executed.
Suggested reading if you want to know more details:
The implementation of iterators in C# and its consequences - Raymond Chen
Part 1
Part 2
Part 3
Iterator block implementation details: auto-generated state machines - Jon Skeet
Eric Lippert's blog
The compiler generates a state-machine on your behalf.
From the language specification:
10.14 Iterators
10.14.4 Enumerator objects
When a function member returning an
enumerator interface type is
implemented using an iterator block,
invoking the function member does not
immediately execute the code in the
iterator block. Instead, an enumerator
object is created and returned. This
object encapsulates the code specified
in the iterator block, and execution
of the code in the iterator block
occurs when the enumerator object’s
MoveNext method is invoked. An
enumerator object has the following
characteristics:
• It implements
IEnumerator and IEnumerator, where
T is the yield type of the iterator.
• It implements System.IDisposable.
• It is initialized with a copy of the
argument values (if any) and instance
value passed to the function member.
• It has four potential states,
before, running, suspended, and after,
and is initially in the before state.
An enumerator object is typically an
instance of a compiler-generated
enumerator class that encapsulates the
code in the iterator block and
implements the enumerator interfaces,
but other methods of implementation
are possible. If an enumerator class
is generated by the compiler, that
class will be nested, directly or
indirectly, in the class containing
the function member, it will have
private accessibility, and it will
have a name reserved for compiler use
(§2.4.2).
To get an idea of this, here's how Reflector decompiles your class:
public class EnumeratorExample
{
// Methods
public static IEnumerable<int> GetSource(int startPoint)
{
return new <GetSource>d__0(-2) { <>3__startPoint = startPoint };
}
// Nested Types
[CompilerGenerated]
private sealed class <GetSource>d__0 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IEnumerator, IDisposable
{
// Fields
private int <>1__state;
private int <>2__current;
public int <>3__startPoint;
private int <>l__initialThreadId;
public int <index>5__3;
public bool <keepSearching>5__2;
public int[] <values>5__1;
public int startPoint;
// Methods
[DebuggerHidden]
public <GetSource>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
this.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId;
}
private bool MoveNext()
{
switch (this.<>1__state)
{
case 0:
this.<>1__state = -1;
this.<values>5__1 = new int[] { 1, 2, 3, 4, 5, 6, 7 };
this.<keepSearching>5__2 = true;
this.<index>5__3 = this.startPoint;
while (this.<keepSearching>5__2)
{
this.<>2__current = this.<values>5__1[this.<index>5__3];
this.<>1__state = 1;
return true;
Label_0073:
this.<>1__state = -1;
this.<index>5__3++;
this.<keepSearching>5__2 = this.<index>5__3 < this.<values>5__1.Length;
}
break;
case 1:
goto Label_0073;
}
return false;
}
[DebuggerHidden]
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
EnumeratorExample.<GetSource>d__0 d__;
if ((Thread.CurrentThread.ManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2))
{
this.<>1__state = 0;
d__ = this;
}
else
{
d__ = new EnumeratorExample.<GetSource>d__0(0);
}
d__.startPoint = this.<>3__startPoint;
return d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return this.System.Collections.Generic.IEnumerable<System.Int32>.GetEnumerator();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
void IDisposable.Dispose()
{
}
// Properties
int IEnumerator<int>.Current
{
[DebuggerHidden]
get
{
return this.<>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return this.<>2__current;
}
}
}
}
Yield is magic.
Well, not really. The compiler generates a full class to generate the enumeration that you're doing. It's basically sugar to make your life simpler.
Read this for an intro.
EDIT: Wrong this. Link changed, check again if you have once.
That's one of the most complex parts of the C# compiler. Best read the free sample chapter of Jon Skeet's C# in Depth (or better, get the book and read it :-)
Implementing iterators the easy way
For further explanations see Marc Gravell's answer here:
Can someone demystify the yield keyword?
Here is an excellent blog series (from Microsoft veteran Raymond Chen) that details how yield works:
https://devblogs.microsoft.com/oldnewthing/20080812-00/?p=21273
https://devblogs.microsoft.com/oldnewthing/20080813-00/?p=21253
https://devblogs.microsoft.com/oldnewthing/20080814-00/?p=21243
https://devblogs.microsoft.com/oldnewthing/20080815-00/?p=21223
What are the best approaches to implementing monads in C#? Are there particular implementation-strategies or is every monad differently implemented from the other?
To answer the question instead of just commenting on it, Linq is probably the foremost method of performing monadic transformations in C#. A Linq method chain is nothing more than a lazily-evaluated, ordered set of list-processing operations.
Linq, of course, is not rocket science; more than your average college-level programming course, but still. It's a series of extension methods that each produce a placeholder enumerable (the monad) containing the logic they should perform, and a reference to their source of data (which can be another monadic encapsulation). You can, and many do, add additional extensions to the basic Linq library to fill holes in the functionality or perform custom actions that meet specific needs.
You can also create your own monadic method chain frameworks, to do practically anything. Pretty much any framework or library described as having a "fluent" coding interface is a monad-based library. There are fluent unit test asserters, fluent ORM configurations, even fluent domain-UI mapping extensions.
Implementing a monadic library in C# is usually done using a static class and static methods, which make use of one or more monadic types which are inaccessible from outside their intended usage. For instance, here is a basic monadic library that performs integer addition and subtraction:
public static class MonadicArithmetic
{
public static Monad Take(int input) { return new Monad(input); }
public class Monad
{
int theValue;
internal Monad(int input) { theValue = input; }
public Monad Add(int input){ return new Monad(theValue + input); }
public Monad Subtract(int input){ return new Monad(theValue - result); }
public int Value { get { return theValue; } }
}
}
...
//usage
var result = MonadicArithmetic.Take(1).Add(2).Subtract(1).Value; //2
Obviously this is very basic, and all operations are performed "eagerly". If those operations were complex, this may not be optimal, so instead, let's perform them "lazily":
public static class MonadicArithmetic
{
public static Monad Take(int input) { return new Monad(input); }
public class Monad
{
//Change the "value keeper" into a Func that will return the value;
Func<int> theValue;
//the constructor now turns the input value into a lambda
internal Monad(int input) { theValue = ()=>input; }
//and another constructor is added for intra-class use that takes a lambda
private Monad(Func<int> input) { theValue = input; }
//And now the methods will create new lambdas that call the existing lambdas
public Monad Add(int input){ return new Monad(()=>theValue() + input); }
public Monad Subtract(int input){ return new Monad(()=>theValue() - input); }
//Finally, our Value getter at the end will evaluate the lambda, unwrapping all the nested calls
public int Value { get { return theValue(); } }
}
}
Same usage, except no operations will be performed until a concrete Value is requested by consuming code:
//Each call just adds a shell to the nested lambdas
var operation = MonadicArithmetic.Take(1).Add(2).Subtract(1);
...
//HERE's the payoff; the result is not evaluated till the call to Value_get() behind the scenes of this assignment.
var result = operation.Value;
However, there's a problem with this. The methods simply take the input values, and reference them in a lambda. The problem is that the values' scope is dependent on the containing method (meaning they don't live long enough for the lambda to be evaluated). When the Value() getter is called, the lambda will be evaluated, and all of these out-of-scope variables will be referenced. Instead, we should persist the values in something that will live at least as long as the lambdas do. The monad is the obvious option. Here is a probable solution:
public static class MonadicArithmetic
{
public static Monad Take(int input) { return new Monad(input); }
public class Monad
{
//Our value keeper is now a pure function that requires no external closures
Func<Func<int>, int, int> operation;
//and we add two new private fields;
//a hook to a lambda that will give us the result of all previous operations,
Func<int> source;
//... and the value for the current operation.
private int addend;
//our constructor now takes the value, stores it, and creates a simple lambda
internal Monad(int input) { addend = input; operation = ()=>addend; }
//and our private constructor now builds a new Monad from scratch
private Monad(Func<int> prevOp, Func<Func<int>, int, int> currOp, int input)
{
source = prevOp,
operation = currOp,
addend = input;
}
//The methods will create new Monads that take the current Monad's value getter,
//keeping the current Monad in memory.
public Monad Add(int input)
{
return new Monad(this.Result, (f,i)=>f()+i, input);
}
public Monad Subtract(int input)
{
return new Monad(this.Result, (f,i)=>f()-i, input);
}
//And we change our property to a method, so it can also
//be used internally as a delegate
public int Result() { return operation(source, addend); }
}
}
//usage
var operations = MonadicArithmetic.Take(1).Add(3).Subtract(2);
//There are now 3 Monads in memory, each holding a hook to the previous Monad,
//the current addend, and a function to produce the result...
...
//so that here, all the necessary pieces are still available.
var result = operations.Result();
This is the basic pattern for a monadic library. The static method that starts the whole thing can be an extension method, which is the style Linq uses. The root of the method chain becomes the first value:
//using an "identity function" to convert to a monad
var operations = 1.AsMonad().Add(2).Subtract(3);
//performing the conversion implicitly from an overload of Add()
var operations = 1.Add(2).Subtract(3);
Linq for objects is particularly elegant in that its libraries are extension methods that take an IEnumerable and return an IEnumerable, so the conversion process is handled without any overloading or explicit method calls. However, IQueryable objects, which hide translatable expression trees, ARE a new idea in .NET 3.5, and you DO have to explicitly convert a collection to an IQueryable, via the AsQueryable() method.