Cω - Samples

Direct Member Access Tutorial

This tutorial shows how to perform direct member access in a simple program.

Sample Files

To run this tutorial, you may use the following project and source files:

These files are located in the \samples\Basics\Duplicates subdirectory under the path where you installed Cω, which by default is C:\Program Files\Comega.

Further Reading

Tutorial

Just as we can access members of a Button instance via b.OK or b.Size.Width, we can also access the direct members of an Email instance using normal "."-notation, for example, hello.Header.From returns the string "Bill". To access the contents of the message body we simply write

string* ps = hello.Body.P;

which returns a stream of strings containing all the P members of our message: "Hi Steve,", "It is time for coffee". Note that the subexpression hello.Body has type struct{ string P; }+ but we were able to directly access the P fields of this stream. What happened is that member access has been transparently lifted over the stream to select the P member of every individual struct in that stream. Without this lifting we would have to write something like:

            string* Ps(){ foreach(s in hello.Body) yield return s.P; };
            string* ps = Ps();

Suppose that we want to select all the direct members of the Header of a message. In C# this would again be very heavy-weight, in Cω we can use wild-card selection

string* header = hello.Header.*;

which returns the stream of strings "Bill", "Steve" . Often plain wild-card queries are too general, for example the query b.* where b is the Button instance we created earlier, will return the values of all the fields and properties of a Button, of which there are quite a few. We can exercise some more control over the members that will be selected based on their static type. For instance, we can select only the members of type bool using the selection b.bool::*.

Duplicates

Being able to select members based on their name and type is very useful when a type has duplicate members, which -- because of an XSD requirement -- is possible in Cω:

struct Duplicates {
  struct{ char b; bool b; }
}
Duplicates d = <Duplicates><b>{'c'}</b><b>{true}</b></Duplicates>
choice{char;bool;}+ bb = d.b;
bool b = d.bool::b; 

This query returns the single value true whereas the expression d.b would return a stream 'c', true that contains the values of both fields.

Example

The following is a complete Cω program demonstrates he concepts discussed above.

using System;

struct Duplicates {
  struct{ char b; bool b; }
}

public class Test {

    static void Main() {

     // create instance of Duplicates
      d = <Duplicates>
             <b>{'c'}</b>
             <b>{true}</b>
          </Duplicates>;

      // select b members returning a stream containing a character and a boolean
      choice{char;bool;}+ bb = d.b;
      bb.{ Console.WriteLine("d.b = {0}", it); };

      // select all boolean members of d
      bool b = d.bool::b;
      Console.WriteLine("d.bool::b = {0}", b);

      Console.ReadLine();

    }
}

Output

d.b = c
d.b = True
d.bool::b = True