using yield in C# like I would in Ruby - c#

Besides just using yield for iterators in Ruby, I also use it to pass control briefly back to the caller before resuming control in the called method. What I want to do in C# is similar. In a test class, I want to get a connection instance, create another variable instance that uses that connection, then pass the variable to the calling method so it can be fiddled with. I then want control to return to the called method so that the connection can be disposed. I guess I'm wanting a block/closure like in Ruby. Here's the general idea:
private static MyThing getThing()
{
using (var connection = new Connection())
{
yield return new MyThing(connection);
}
}
[TestMethod]
public void MyTest1()
{
// call getThing(), use yielded MyThing, control returns to getThing()
// for disposal
}
[TestMethod]
public void MyTest2()
{
// call getThing(), use yielded MyThing, control returns to getThing()
// for disposal
}
...
This doesn't work in C#; ReSharper tells me that the body of getThing cannot be an iterator block because MyThing is not an iterator interface type. That's definitely true, but I don't want to iterate through some list. I'm guessing I shouldn't use yield if I'm not working with iterators. Any idea how I can achieve this block/closure thing in C# so I don't have to wrap my code in MyTest1, MyTest2, ... with the code in getThing()'s body?

What you want are lambda expressions, something like:
// not named GetThing because it doesn't return anything
private static void Thing(Action<MyThing> thing)
{
using (var connection = new Connection())
{
thing(new MyThing(connection));
}
}
// ...
// you call it like this
Thing(t=>{
t.Read();
t.Sing();
t.Laugh();
});
This captures t the same way yield does in Ruby. The C# yield is different, it constructs generators that can be iterated over.

You say you want to use C#'s yield keyword the same way you would use Ruby's yield keyword. You seem to be a little confused about what the two actually do: the two have absolutely nothing to do with each other, what you are asking for, is simply not possible.
The C# yield keyword is not the C# equivalent of the Ruby yield keyword. In fact, there is no equivalent to the Ruby yield keyword in C#. And the Ruby equivalent to C#'s yield keyword is not the yield keyword, it's the Enumerator::Yielder#yield method (also aliased as Enumerator::Yielder#<<).
IOW, it's for returning the next element of an iterator. Here's an abridged example from the official MSDN documentation:
public static IEnumerable Power(int number, int exponent) {
var counter = 0;
var result = 1;
while (counter++ < exponent) {
result *= number;
yield return result; }}
Use it like so:
foreach (int i in Power(2, 8)) { Console.Write("{0} ", i); }
The Ruby equivalent would be something like:
def power(number, exponent)
Enumerator.new do |yielder|
result = 1
1.upto(exponent-1) { yielder.yield result *= number } end end
puts power(2, 8).to_a
In C#, yield is used to yield a value to the caller and in Ruby, yield is used to yield control to a block argument
In fact, in Ruby, yield is just a shortcut for Proc#call.
Imagine, if yield didn't exist. How would you write an if method in Ruby? It would look like this:
class TrueClass
def if(code)
code.call
end
end
class FalseClass
def if(_); end
end
true.if(lambda { puts "It's true!" })
This is kind of cumbersome. In Ruby 1.9, we get proc literals and a shortcut syntax for Proc#call, which make it a little bit nicer:
class TrueClass
def if(code)
code.()
end
end
true.if(->{ puts "It's true!' })
However, Yukihiro Matsumoto noticed, that the vast majority of higher-order procedures only take one procedure argument. (Especially since Ruby has several control-flow constructs built into the language, which would otherwise require multiple procedure arguments, like if-then-else which would require two and case-when which would require n arguments.) So, he created a specialized way to pass exactly one procedural argument: the block. (In fact, we already saw an example of this at the very beginning, because Kernel#lambda is actually just a normal method which takes a block and returns a Proc.)
class TrueClass
def if(&code)
code.()
end
end
true.if { puts "It's true!" }
Now, since we can only ever pass exactly one block into a method, we really don't need to explicitly name the variable, since there can never be an ambiguity anyway:
def if
???.() # But what do we put here? We don't have a name to call #call on!
end
However, since we now no longer have a name that we can send messages to, we need some other way. And again, we get one of those 80/20 solutions that are so typical for Ruby: there are tons of things that one might want to do with a block: transform it, store it in an attribute, pass it to another method, inspect it, print it … However, by far the most common thing to do is to call it. So, matz added another specialized shortcut syntax for exactly this common case: yield means "call the block that was passed to the method". Therefore, we don't need a name:
def if; yield end
So, what is the C# equivalent to Ruby's yield keyword? Well, let's go back to the first Ruby example, where we explicitly passed the procedure as an argument:
def foo(bar)
bar.('StackOverflow')
end
foo ->name { puts "Higher-order Hello World from #{name}!" }
The C# equivalent is exactly the same:
void Foo(Action<string> bar) => bar("StackOverflow")
Foo(name => { Console.WriteLine("Higher-order Hello World from {0]!", name); })

I might pass a delegate into the iterator.
delegate void Action(MyThing myThing);
private static void forEachThing(Action action)
{
using (var connection = new Connection())
{
action(new MyThing(connection));
}
}

yield in C# is specifically for returning bits of an iterated collection. Specifically, your function has to return IEnumerable<Thing> or IEnumerable for yield to work, and it's meant to be used from inside of a foreach loop. It is a very specific construct in c#, and it can't be used in the way you're trying.
I'm not sure off the top of my head if there's another construct that you could use or not, possibly something with lambda expressions.

You can have GetThing take a delegate containing the code to execute, then pass anonymous methods from other functions.

Related

What does _= mean in C#? [duplicate]

While going through new C# 7.0 features, I stuck up with discard feature. It says:
Discards are local variables which you can assign but cannot read
from. i.e. they are “write-only” local variables.
and, then, an example follows:
if (bool.TryParse("TRUE", out bool _))
What is real use case when this will be beneficial? I mean what if I would have defined it in normal way, say:
if (bool.TryParse("TRUE", out bool isOK))
The discards are basically a way to intentionally ignore local variables which are irrelevant for the purposes of the code being produced. It's like when you call a method that returns a value but, since you are interested only in the underlying operations it performs, you don't assign its output to a local variable defined in the caller method, for example:
public static void Main(string[] args)
{
// I want to modify the records but I'm not interested
// in knowing how many of them have been modified.
ModifyRecords();
}
public static Int32 ModifyRecords()
{
Int32 affectedRecords = 0;
for (Int32 i = 0; i < s_Records.Count; ++i)
{
Record r = s_Records[i];
if (String.IsNullOrWhiteSpace(r.Name))
{
r.Name = "Default Name";
++affectedRecords;
}
}
return affectedRecords;
}
Actually, I would call it a cosmetic feature... in the sense that it's a design time feature (the computations concerning the discarded variables are performed anyway) that helps keeping the code clear, readable and easy to maintain.
I find the example shown in the link you provided kinda misleading. If I try to parse a String as a Boolean, chances are I want to use the parsed value somewhere in my code. Otherwise I would just try to see if the String corresponds to the text representation of a Boolean (a regular expression, for example... even a simple if statement could do the job if casing is properly handled). I'm far from saying that this never happens or that it's a bad practice, I'm just saying it's not the most common coding pattern you may need to produce.
The example provided in this article, on the opposite, really shows the full potential of this feature:
public static void Main()
{
var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010);
Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}");
}
private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int year2)
{
int population1 = 0, population2 = 0;
double area = 0;
if (name == "New York City")
{
area = 468.48;
if (year1 == 1960) {
population1 = 7781984;
}
if (year2 == 2010) {
population2 = 8175133;
}
return (name, area, year1, population1, year2, population2);
}
return ("", 0, 0, 0, 0, 0);
}
From what I can see reading the above code, it seems that the discards have a higher sinergy with other paradigms introduced in the most recent versions of C# like tuples deconstruction.
For Matlab programmers, discards are far from being a new concept because the programming language implements them since very, very, very long time (probably since the beginning, but I can't say for sure). The official documentation describes them as follows (link here):
Request all three possible outputs from the fileparts function:
helpFile = which('help');
[helpPath,name,ext] = fileparts('C:\Path\data.txt');
The current workspace now contains three variables from fileparts: helpPath, name, and ext. In this case, the variables are small. However, some functions return results that use much more memory. If you do not need those variables, they waste space on your system.
Ignore the first output using a tilde (~):
[~,name,ext] = fileparts(helpFile);
The only difference is that, in Matlab, inner computations for discarded outputs are normally skipped because output arguments are flexible and you can know how many and which one of them have been requested by the caller.
I have seen discards used mainly against methods which return Task<T> but you don't want to await the output.
So in the example below, we don't want to await the output of SomeOtherMethod() so we could do something like this:
//myClass.cs
public async Task<bool> Example() => await SomeOtherMethod()
// example.cs
Example();
Except this will generate the following warning:
CS4014 Because this call is not awaited, execution of the
current method continues before the call is completed. Consider
applying the 'await' operator to the result of the call.
To mitigate this warning and essentially ensure the compiler that we know what we are doing, you can use a discard:
//myClass.cs
public async Task<bool> Example() => await SomeOtherMethod()
// example.cs
_ = Example();
No more warnings.
To add another use case to the above answers.
You can use a discard in conjunction with a null coalescing operator to do a nice one-line null check at the start of your functions:
_ = myParam ?? throw new MyException();
Many times I've done code along these lines:
TextBox.BackColor = int32.TryParse(TextBox.Text, out int32 _) ? Color.LightGreen : Color.Pink;
Note that this would be part of a larger collection of data, not a standalone thing. The idea is to provide immediate feedback on the validity of each field of the data they are entering.
I use light green and pink rather than the green and red one would expect--the latter colors are dark enough that the text becomes a bit hard to read and the meaning of the lighter versions is still totally obvious.
(In some cases I also have a Color.Yellow to flag something which is not valid but neither is it totally invalid. Say the parser will accept fractions and the field currently contains "2 1". That could be part of "2 1/2" so it's not garbage, but neither is it valid.)
Discard pattern can be used with a switch expression as well.
string result = shape switch
{
Rectangule r => $"Rectangule",
Circle c => $"Circle",
_ => "Unknown Shape"
};
For a list of patterns with discards refer to this article: Discards.
Consider this:
5 + 7;
This "statement" performs an evaluation but is not assigned to something. It will be immediately highlighted with the CS error code CS0201.
// Only assignment, call, increment, decrement, and new object expressions can be used as a statement
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0201?f1url=%3FappId%3Droslyn%26k%3Dk(CS0201)
A discard variable used here will not change the fact that it is an unused expression, rather it will appear to the compiler, to you, and others reviewing your code that it was intentionally unused.
_ = 5 + 7; //acceptable
It can also be used in lambda expressions when having unused parameters:
builder.Services.AddSingleton<ICommandDispatcher>(_ => dispatcher);

Do C# closures support non-local returns? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
To explain the matter here is some Scala code:
object Scratch {
def foo: Int = {
val list = List(1, 2, 3, 4)
list.foreach { each =>
if(each > 2) {
return each
}
println(each)
}
return 5
}
def main(args : Array[String]) : Unit = {
val i = foo
println("i: " + i)
}
The code above prints this to the console:
1
2
i: 3
In particular, note that the closure used by list.foreach has a return statement, and this return statement causes foo, the caller of list.foreach, to return, interrupting the foreach enumeration and providing the actual return value for foo. This return is not declared within the foo method itself, and so is a "non-local return".
The question is now how the same thing would turn out in C#, e.g. will something else be printed to the console? The question is about non-local returns in C# from inside closures. Only if they are supported the same output would occur as in the code above.
Note: This is no speciality of Scala. Other language have this as well like Smalltalk or Kotlin, probably also Ruby and others for sure.
I wanted to try this out myself, but after downloadinng 9 GB for installing Visual Studio 2017 I was told to upgrade to Windows 10 and that was not what I wanted to do just to get this question answered.
No, C# does not support non-local returns in closures. A C# closure is a method unto itself, and does not share context (other than captured variables) with its enclosing method. When you return from within a lambda expression, you are returning from that method, i.e. the anonymous method the lambda refers to. It doesn't affect the method in which the lambda is declared, nor the method from which the lambda is invoked (if different from that in which it's declared).
I'm not that familiar with either Scala or Ruby, but it appears that Scala is more similar to Ruby than to C#. If so, I take it that non-local returns cause the calling method to return. It just happens in your example that the calling method is the same as the declaring method, but for obvious reasons it would be pretty odd for a lambda to cause the declaring method to return. I.e. the lambda might be invoked after the declaring method has already returned. There's more in-depth discussion of Ruby (and by inference, Scala) at the Stack Overflow question Is Ruby's code block same as C#'s lambda expression?.
Of course, you can still accomplish the same effect in C#. It's just that the exact syntax you're using won't do that. In .NET, the List<T> generic class has a ForEach() method, so taking your code example literally (i.e. using that built-in ForEach() method), this is the closest you can come in C#:
static void Main(string[] args)
{
var i = foo();
WriteLine($"i: {i}");
}
static int foo()
{
var list = new List<int> { 1, 2, 3, 4 };
try
{
list.ForEach(each =>
{
if (each > 2)
{
throw new LocalReturnException(each);
}
WriteLine(each);
});
}
catch (LocalReturnException e)
{
return e.Value;
}
return 5;
}
class LocalReturnException : Exception
{
public int Value { get; }
public LocalReturnException(int value)
{
Value = value;
}
}
Because the List<T>.ForEach() method does not provide any mechanism to interrupt its enumeration of the source enumerable, the only way to get the method to return prematurely is to bypass the normal method-returning mechanisms by throwing an exception.
Of course, exceptions are fairly heavy-weight. There's a marginal cost just for the try/catch handler, and actually throwing and catching one is very costly. If you have a need for this idiom, it would be better to create your own enumeration method which provides for a mechanism to interrupt the enumeration and return a value. For example, create extension methods like so:
public static T? InterruptableForEach<T>(this IEnumerable<T> source, Func<T, T?> action)
where T : struct
{
foreach (T t in source)
{
T? result = action(t);
if (result != null) return result;
}
return null;
}
public static T InterruptableForEach<T>(this IEnumerable<T> source, Func<T, T> action)
where T : class
{
foreach (T t in source)
{
T result = action(t);
if (result != null) return result;
}
return null;
}
The first is needed for your example. I show two, because C# treats value types like int differently from reference types when it comes to null values, but the second isn't strictly needed here.
With the extension method, you can then do something like this:
static int foo()
{
var list = new List<int> { 1, 2, 3, 4 };
var result = list.InterruptableForEach(each =>
{
if (each > 2)
{
return each;
}
WriteLine(each);
return null;
});
return result ?? 5;
}
Note that the caller needs to cooperate with the lambda and the extension method. That is, the extension method is explicitly reporting what the lambda itself returned, so that it knows whether the lambda returned prematurely and if so, what the value is.
On the one hand, this is a bit more clumsy and verbose than the Scala version. On the other hand, it's consistent with C#'s tendency toward explicitness and expressiveness, and avoidance of ambiguous situations (such as, what if the foo() method didn't return an int, but the lambda did?).
This answer shows yet another possible approach. I personally would prefer either of the above, as they both actually interrupt the enumeration, rather than just skip the main lambda body until the end of the enumeration (which could be a problem for infinite enumerations), and don't introduce the additional captured variables required by that answer. But it does work in your example.
this are my answers to your questions:
1)
You dont need to install anything for playing arround with C# and LINQ. You can simply use https://dotnetfiddle.net
2) Here is my code https://dotnetfiddle.net/3V8vBj
using System.Collections.Generic;
public class Program
{
static int foo()
{
var list = new List<int> { 1, 2, 3, 4 };
int ret = 5;
bool keepGoing = true;
list.ForEach(each =>
{
if (!keepGoing)
return;
if (each>2)
{
ret=each;
keepGoing = false;
return;
}
System.Console.WriteLine(each);
});
return ret;
}
public static void Main(string[] args)
{
var i = foo();
System.Console.WriteLine("i: " + i);
}
}
3) When you using LINQ Foreach you can not simply break it for return, since it is a delegate function. So I had to implement keepGoing.
4) The nested delegate function can not return a value, so I have to use "ret" for setting the return inside the LINQ Foreach.
I hope this answers your question, but I am not really sure that I understand it right.

Java equivalent to IEnumerator from C#?

Are there interfaces in Java library, which also enumerates some series, but follows slightly another logic than Iterator and Enumeration? Namely they should return boolean on next(), saying whether next element was reached, and should have getCurrent() method, which returns current element?
UPDATE
Iterator.next() is not equivalent of IEnumerator.Current since former will advance iterator on each call while latter won't.
UPDATE 2
I am designing my own class with my own functionality. My question was in order to find a "competent" analogy. The sample from C# was just a sample, I am not translating something from C# to Java.
This sounds like Guava's PeekingIterator; you can decorate a plain Iterator with Iterators.peekingIterator.
You have to use a different approach in Java.
e.g., instead of this C# code:
Dictionary<int?, int?> m = new Dictionary<int?, int?>();
for (IEnumerator<KeyValuePair<int?, int?>> it = m.GetEnumerator(); it.MoveNext();)
{
Console.Write(it.Current.Key);
Console.Write(it.Current.Value);
}
You will need to use:
java.util.HashMap<Integer, Integer> m = new java.util.HashMap<Integer, Integer>();
for (java.util.Iterator<java.util.Map.Entry<Integer, Integer>> it = m.entrySet().iterator(); it.hasNext();)
{
java.util.Map.Entry<Integer, Integer> current = it.next();
System.out.print(current.getKey());
System.out.print(current.getValue());
}
There should not be a high demand for this particular conversion since you would normally use a 'foreach' loop in C#, which would convert more cleanly to Java.
If you use a standard concrete Collection class, such as HashSet and ArrayList to name but two, you will have access to an iterator.
Calling the method: collection.hasNext() will return a boolean, but not advance the pointer. This will allow you to determine whether you should attempt to read collection.next().
Example:
Set<String> numbers = new HashSet<>();
// fill in set...
while (numbers.hasNext()) {
System.out.println(numbers.next());
}
Of course, you can also iterate through a collection using the for-each syntax:
for (String s : numbers) {
System.out.println(s)
}

Why can iterators in structs modify this?

I discovered that iterator methods in value types are allowed to modify this.
However, due to limitations in the CLR, the modifications are not seen by the calling method. (this is passed by value)
Therefore, identical code in an iterator and a non-iterator produce different results:
static void Main() {
Mutable m1 = new Mutable();
m1.MutateWrong().ToArray(); //Force the iterator to execute
Console.WriteLine("After MutateWrong(): " + m1.Value);
Console.WriteLine();
Mutable m2 = new Mutable();
m2.MutateRight();
Console.WriteLine("After MutateRight(): " + m2.Value);
}
struct Mutable {
public int Value;
public IEnumerable<int> MutateWrong() {
Value = 7;
Console.WriteLine("Inside MutateWrong(): " + Value);
yield break;
}
public IEnumerable<int> MutateRight() {
Value = 7;
Console.WriteLine("Inside MutateRight(): " + Value);
return new int[0];
}
}
Output:
Inside MutateWrong(): 7
After MutateWrong(): 0
Inside MutateRight(): 7
After MutateRight(): 7
Why isn't it a compiler error (or at least warning) to mutate a struct in an iterator?
This behavior is a subtle trap which is not easily understood.
Anonymous methods, which share the same limitation, cannot use this at all.
Note: mutable structs are evil; this should never come up in practice.
In order to justify a warning, it should be in a situation where the programmer is likely to get unexpected results. According to Eric Lippert, "we try to reserve warnings for only those situations where we can say with almost certainty that the code is broken, misleading or useless." Here is an instance where the warning would be misleading.
Let's say you have this perfectly valid – if not terribly useful – object:
struct Number
{
int value;
public Number(int value) { this.value = value; }
public int Value { get { return value; } }
// iterator that mutates "this"
public IEnumerable<int> UpTo(int max)
{
for (; value <= max; value++)
yield return value;
}
}
And you have this loop:
var num = new Number(1);
foreach (var x in num.UpTo(4))
Console.WriteLine(num.Value);
You'd expect this loop to print 1,1,1,1, not 1,2,3,4, right? So the class works exactly as you expect. This is an instance where the warning would be unjustified.
Since this is clearly not a situation where the code is broken, misleading, or useless, how would you propose that the compiler generate an error or warning?
To cite yourself "mutable structs are evil" :)
The same thing as you experienced happens if you implement an extension method for a struct.
If you try to modify the struct within the extension method you still will have your original struct unchanged.
It is a bit less surprising since the extension method signature looks like:
static void DoSideEffects(this MyStruct x) { x.foo = ...
Looking at it we realize that something like parameter passing happens and therefore the struct is copied. But when you use the extension it looks like:
x.DoSideEffects()
and you will be surprised not to have any effects on your variable x.
I suppose that behind the scenes your yield constructs do something similar to extensions.
I would phrase the starting sentence harder:
"structs are evil" .. in general ;)
I had a similar thought to what Gabe said. It seems at least theoretically possible that one might opt to use a struct to behave kind of like a method, encapsulating that method's local variables as instance fields:
struct Evens
{
int _current;
public IEnumerable<int> Go()
{
while (true)
{
yield return _current;
_current += 2;
}
}
}
I mean, it's kind of weird, obviously. It kind of reminds me of ideas I've encountered in the past, though, where developers have concocted ever-stranger ways of calling methods, such as wrapping a method's parameters into an object and letting that object call the method—going backwards, in a sense. I'd say that's roughly what this is.
I'm not saying this would be a wise thing to do, but it is at least a way of using this in the way you are describing that might be intentional, and would technically exhibit correct behavior.
It's not really clear what should happen, though I think .net is deficient in not requiring a special attribute for methods which modify 'this'; such an attribute could be useful applied to immutable class types as well as mutable structs. Methods which are tagged with such an attribute should only be usable on structure variables, fields, and parameters, and not on temporary values.
I don't think there's any way to avoid having the iterator capture the struct by value. It's entirely possible that by the time an iterator is used, the original struct upon which it was based may not exist anymore. On the other hand, if the struct implemented an interface that inherited IEnumerable<int>, but also included a function to return Value, casting the struct to that interface type before using the enumerator could in theory allow the iterator to keep a reference to the struct without having to recopy its value; I wouldn't be at all surprised if the enumerator copies the struct by value even in that case, though.

Why are LINQ extensions written in a very difficult to read way?

I was checking some of the code that make up LINQ extensions in Reflector, and this is the kind of code I come across:
private bool MoveNext()
{
bool flag;
try
{
switch (this.<>1__state)
{
case 0:
this.<>1__state = -1;
this.<set>5__7b = new Set<TSource>(this.comparer);
this.<>7__wrap7d = this.source.GetEnumerator();
this.<>1__state = 1;
goto Label_0092;
case 2:
this.<>1__state = 1;
goto Label_0092;
default:
goto Label_00A5;
}
Label_0050:
this.<element>5__7c = this.<>7__wrap7d.Current;
if (this.<set>5__7b.Add(this.<element>5__7c))
{
this.<>2__current = this.<element>5__7c;
this.<>1__state = 2;
return true;
}
Label_0092:
if (this.<>7__wrap7d.MoveNext())
{
goto Label_0050;
}
this.<>m__Finally7e();
Label_00A5:
flag = false;
}
fault
{
this.System.IDisposable.Dispose();
}
return flag;
}
Was there a reason for Microsoft to write it this way?
Also what does the <> syntax mean, in lines like:
switch (this.<>1__state)
I have never seen it written before a variable, only after.
The MSIL is still valid 2.x code and the <> names you're seeing are auto generated by the C# 3.x compilers.
For example:
public void AttachEvents()
{
_ctl.Click += (sender,e) => MessageBox.Show( "Hello!" );
}
Translates to something like:
public void AttachEvents()
{
_ctl.Click += new EventHandler( <>b_1 );
}
private void <>b_1( object sender, EventArgs e )
{
MessageBox.Show( "Hello!" );
}
I should also note that the reason you're seeing it like that in Reflector is that you don't have .NET 3.5 optimization turned on. Go to View | Options and change Optimization to .NET 3.5 and it will do a better job of translating the generated identifiers back to their lamda expressions.
You're seeing the internal guts of the finite state machines that the C# compiler emits on your behalf when it handles iterators.
Jon Skeet has some great articles (Iterator block implementation details and Iterators, iterator blocks and data pipelines) on this subject. See also Chapter 6 of his book.
There was previously an SO post on this subject.
And, finally, Microsoft Research has a nice paper on the subject.
Read until your heart is content.
Identifiers starting with <> aren't valid C# identifiers, so I suspect they use them to mangle the names without fear of conflict, as no identifier in the C# code could be the same.
As to why it's hard to read, I suspect that it's more down to the fact it's easy to generate.
This is code that is automatically generated when you use iterators. The <> is used to ensure there are no collisions, and also to prevent you from accessing the compiler-generator classes directly in your code.
See the following for more information:
Using C# Yield for Readability and Performance
C# Iterators
These are types that have been auto-generated by the compiler from iterator methods.
The compiler will do exactly the same sort of thing to your own iterators. For example, write something like this and then take a look at the actual generated code in Reflector:
public IEnumerable<int> GetRandom()
{
Random rng = new Random();
while (true)
{
yield return rng.Next();
}
}
This is state machine that is automatically generated from an iterator, such as the following:
static IEnumerable<Func<KeyValuePair<int, int>>> FunnyMethod() {
for (var i = 0; i < 10; i++) {
var localVar = i;
yield return () => new KeyValuePair(localVar, i);
}
}
This method will return 10 for all of the values.
The compiler transforms these methods into state machines that store their state in the <>1__state field and call each part of the iterator for a different value of the field.
The <> part is part of the generated field name, and is chosen so as not to conflict with anything.
You must understand what Reflector does. It is not getting the source code back. That's not what a developer at MS wrote. :) It takes Intermediate Language (IL) and systematically converts it back to C# (or VB.NET). In doing so, it must come up with an approach. As you know there are many ways to skin a cat in code that will eventually lead to the same IL. Reflector has to pick a way to move back wards from IL to a higher level language and use that way every time.
(Fixed per comment, thank you.)

Categories