// example based on the MSDN Collection Classes Sample (tokens2.cs) public static void GenTokens2(AssemblyGen ag) { TypeGen Tokens = ag.Public.Class("Tokens", typeof(object), typeof(IEnumerable)); { FieldGen elements = Tokens.Private.Field(typeof(string[]), "elements"); CodeGen g = Tokens.Constructor() .Parameter(typeof(string), "source") .Parameter(typeof(char[]), "delimiters") ; { g.Assign(elements, g.Arg("source").Invoke("Split", g.Arg("delimiters"))); } // Inner class implements IEnumerator interface: TypeGen TokenEnumerator = Tokens.Public.Class("TokenEnumerator", typeof(object), typeof(IEnumerator)); { FieldGen position = TokenEnumerator.Field(typeof(int), "position", -1); FieldGen t = TokenEnumerator.Field(Tokens, "t"); g = TokenEnumerator.Public.Constructor().Parameter(Tokens, "tokens"); { g.Assign(t, g.Arg("tokens")); } g = TokenEnumerator.Public.Method(typeof(bool), "MoveNext"); { g.If(position < t.Field("elements").ArrayLength() - 1); { g.Increment(position); g.Return(true); } g.Else(); { g.Return(false); } g.End(); } g = TokenEnumerator.Public.Method(typeof(void), "Reset"); { g.Assign(position, -1); } // non-IEnumerator version: type-safe g = TokenEnumerator.Public.Property(typeof(string), "Current").Getter(); { g.Return(t.Field("elements")[position]); } // IEnumerator version: returns object g = TokenEnumerator.Public.PropertyImplementation(typeof(IEnumerator), typeof(object), "Current").Getter(); { g.Return(t.Field("elements")[position]); } } // IEnumerable Interface Implementation: // non-IEnumerable version g = Tokens.Public.Method(TokenEnumerator, "GetEnumerator"); { g.Return(Exp.New(TokenEnumerator, g.This())); } // IEnumerable version g = Tokens.Public.MethodImplementation(typeof(IEnumerable), typeof(IEnumerator), "GetEnumerator"); { g.Return(Exp.New(TokenEnumerator, g.This()).Cast(typeof(IEnumerator))); } // Test Tokens, TokenEnumerator g = Tokens.Static.Method(typeof(void), "Main"); { Operand f = g.Local(Exp.New(Tokens, "This is a well-done program.", Exp.NewInitializedArray(typeof(char), ' ', '-'))); Operand item = g.ForEach(typeof(string), f); // try changing string to int { g.WriteLine(item); } g.End(); } } }
// example based on the MSDN Operator Overloading Sample (dbbool.cs) public static void GenDbBool(AssemblyGen ag) { TypeGen DBBool = ag.Public.Struct("DBBool"); { // Private field that stores -1, 0, 1 for dbFalse, dbNull, dbTrue: FieldGen value = DBBool.Field <int>("value"); // Private constructor. The value parameter must be -1, 0, or 1: CodeGen g = DBBool.Constructor().Parameter <int>("value"); { g.Assign(value, g.Arg("value")); } // The three possible DBBool values: FieldGen dbNull = DBBool.Public.Static.ReadOnly.Field(DBBool, "dbNull", Exp.New(DBBool, 0)); FieldGen dbFalse = DBBool.Public.Static.ReadOnly.Field(DBBool, "dbFalse", Exp.New(DBBool, -1)); FieldGen dbTrue = DBBool.Public.Static.ReadOnly.Field(DBBool, "dbTrue", Exp.New(DBBool, 1)); // Implicit conversion from bool to DBBool. Maps true to // DBBool.dbTrue and false to DBBool.dbFalse: g = DBBool.ImplicitConversionFrom <bool>("x"); { Operand x = g.Arg("x"); g.Return(x.Conditional(dbTrue, dbFalse)); } // Explicit conversion from DBBool to bool. Throws an // exception if the given DBBool is dbNull, otherwise returns // true or false: g = DBBool.ExplicitConversionTo <bool>("x"); { Operand x = g.Arg("x"); g.If(x.Field("value") == 0); { g.Throw(Exp.New(typeof(InvalidOperationException))); } g.End(); g.Return(x.Field("value") > 0); } // Equality operator. Returns dbNull if either operand is dbNull, // otherwise returns dbTrue or dbFalse: g = DBBool.Operator(Operator.Equality, DBBool, DBBool, "x", DBBool, "y"); { Operand x = g.Arg("x"), y = g.Arg("y"); g.If(x.Field("value") == 0 || y.Field("value") == 0); { g.Return(dbNull); } g.End(); g.Return((x.Field("value") == y.Field("value")).Conditional(dbTrue, dbFalse)); } // Inequality operator. Returns dbNull if either operand is // dbNull, otherwise returns dbTrue or dbFalse: g = DBBool.Operator(Operator.Inequality, DBBool, DBBool, "x", DBBool, "y"); { Operand x = g.Arg("x"), y = g.Arg("y"); g.If(x.Field("value") == 0 || y.Field("value") == 0); { g.Return(dbNull); } g.End(); g.Return((x.Field("value") != y.Field("value")).Conditional(dbTrue, dbFalse)); } // Logical negation operator. Returns dbTrue if the operand is // dbFalse, dbNull if the operand is dbNull, or dbFalse if the // operand is dbTrue: g = DBBool.Operator(Operator.LogicalNot, DBBool, DBBool, "x"); { Operand x = g.Arg("x"); g.Return(Exp.New(DBBool, -x.Field("value"))); } // Logical AND operator. Returns dbFalse if either operand is // dbFalse, dbNull if either operand is dbNull, otherwise dbTrue: g = DBBool.Operator(Operator.And, DBBool, DBBool, "x", DBBool, "y"); { Operand x = g.Arg("x"), y = g.Arg("y"); g.Return(Exp.New(DBBool, (x.Field("value") < y.Field("value")).Conditional(x.Field("value"), y.Field("value")))); } // Logical OR operator. Returns dbTrue if either operand is // dbTrue, dbNull if either operand is dbNull, otherwise dbFalse: g = DBBool.Operator(Operator.Or, DBBool, DBBool, "x", DBBool, "y"); { Operand x = g.Arg("x"), y = g.Arg("y"); g.Return(Exp.New(DBBool, (x.Field("value") > y.Field("value")).Conditional(x.Field("value"), y.Field("value")))); } // Definitely true operator. Returns true if the operand is // dbTrue, false otherwise: g = DBBool.Operator(Operator.True, typeof(bool), DBBool, "x"); { Operand x = g.Arg("x"); g.Return(x.Field("value") > 0); } // Definitely false operator. Returns true if the operand is // dbFalse, false otherwise: g = DBBool.Operator(Operator.False, typeof(bool), DBBool, "x"); { Operand x = g.Arg("x"); g.Return(x.Field("value") < 0); } // Overload the conversion from DBBool to string: g = DBBool.ImplicitConversionTo(typeof(string), "x"); { Operand x = g.Arg("x"); g.Return((x.Field("value") > 0).Conditional("dbTrue", (x.Field("value") < 0).Conditional("dbFalse", "dbNull"))); } // Override the Object.Equals(object o) method: g = DBBool.Public.Override.Method <bool>("Equals").Parameter <object>("o"); { g.Try(); { g.Return((g.This() == g.Arg("o").Cast(DBBool)).Cast <bool>()); } g.CatchAll(); { g.Return(false); } g.End(); } // Override the Object.GetHashCode() method: g = DBBool.Public.Override.Method <int>("GetHashCode"); { g.Return(value); } // Override the ToString method to convert DBBool to a string: g = DBBool.Public.Override.Method <string>("ToString"); { g.Switch(value); { g.Case(-1); g.Return("DBBool.False"); g.Case(0); g.Return("DBBool.Null"); g.Case(1); g.Return("DBBool.True"); g.DefaultCase(); g.Throw(Exp.New <InvalidOperationException>()); } g.End(); } } TypeGen Test = ag.Class("Test"); { CodeGen g = Test.Static.Void("Main"); { Operand a = g.Local(DBBool), b = g.Local(DBBool); g.Assign(a, Static.Field(DBBool, "dbTrue")); g.Assign(b, Static.Field(DBBool, "dbNull")); g.WriteLine("!{0} = {1}", a, !a); g.WriteLine("!{0} = {1}", b, !b); g.WriteLine("{0} & {1} = {2}", a, b, a & b); g.WriteLine("{0} | {1} = {2}", a, b, a | b); // Invoke the true operator to determine the Boolean // value of the DBBool variable: g.If(b); { g.WriteLine("b is definitely true"); } g.Else(); { g.WriteLine("b is not definitely true"); } g.End(); } } }