예제 #1
0
        // 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();
                }
            }
        }