This tutorial shows how to perform direct member access in a simple program.
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.
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::*.
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.
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();
}
}
d.b = c d.b = True d.bool::b = True