You're right, there were missing tokens; sorry about that.

Here is the equivalent C# 6 version of the code (i.e. something very similar to the pattern that I currently use):

IEnumerable<Student> GetStudents(SqlCommand cmd)
{
var rdr = cmd.ExecuteReader();
var memo = new Dictionary<int, Student.Completion>();

while(rdr.Read())
{
Student.Completion completion; //this declaration will be unnecessary in C# 7

if(!memo.TryGetValue(rdr.GetInt32("student_id"), out completion))
memo.Add(new Student(rdr, out completion).ID, completion);

completion.AddCourse(rdr); //completion is *guaranteed* to be non-null
}

return from kv in memo select kv.Value.Student;
}

As you can see, it only differs from the C# 7 version by one line.

The first thing to note is that, per the C# spec, the `out` parameters of a method must be definitely assigned before the method returns[1]. It just so happens that the constructor of the `Student` class always creates a new `Completion` object and assigns it to the `out` parameter. Now, theoretically, an `out` parameter could be assigned a null reference (as in the case of TryGetValue), but in practice it's trivial to guarantee that it will be non-null (as in the case of our Student cstor).

In the line,

memo.Add(new Student(rdr, out completion).ID, completion);

we first call the Student cstor, which assigns a non-null value to completion, so that by the time `memo.Add` is called, the completion variable is guaranteed to be non-null.

Also, `Student.Completion` is a class that is defined inside of the `Student` class. As such, it has access to all of Student's members (private and public). But, in order to do anything to an instance of Student, a Completion instance must have field which references that Student instance (unlike the case of Java's inner classes, which are a bit more powerful I think). That is why this line is possible:

return from kv in memo select kv.Value.Student //`Value` is an instance of Student.Completion

Here is the basic definition of the Student class:

sealed class Student
{
public int ID { get; } //this is a readonly property, meaning it can only be modified in a cstor
public FullName { get; } //readonly property

private List<Course> courses = new List<Courses>();

public IEnumerable<Course> Courses => from c in courses select c;

public Student(IDataReader rdr, out Completion completion)
{
ID = rdr.GetInt32("student_id");
Fullname = rdr.GetString("fullname");

completion = new Completion(this);
}

public sealed class Completion
{
public Student Student { get; } //readonly property.

public Completion(Student student)
{
this.Student = student;
}

public void AddCourse(IDataReader rdr)
{
if(rdr.GetInt32("student_id) == Student.ID)
student.courses.Add(new Course(rdr));
}
}
}

Like I said in my earlier comment, my immediate goal was to be able to create a set of immutable objects with arbitrary nestings from the result of a single SQL query that may have an arbitrary number of joins (which is how we represent nesting relationally). The above example just has just one nested property, but I have production code in which objects have many more nested properties. For example, the `Course` class in the aforementioned example might have its own `Completion` class for adding `CourseAssignment` instances (e.g. select from Student left join Course on ... left join CourseAssignment on ...).

But, the really big idea is that I wanted an object-capability system[2][3]. Getting objects be immutable "almost everywhere"[4] is a nice side benefit.

[1] http://www.ecma-international.org/publications/files/ECMA-ST... (section 12.1.6)

[2] https://en.wikipedia.org/wiki/Object-capability_model

[3] https://www.youtube.com/watch?v=EGX2I31OhBE

[4] https://en.wikipedia.org/wiki/Almost_everywhere (in this case "almost everywhere" is with respect to the set of all possible execution paths).