public override bool Define (TypeContainer parent) { int length = 1; MethodName = "op_" + OperatorType; if (SecondArgType != null) length = 2; Parameter [] param_list = new Parameter [length]; if ((ModFlags & RequiredModifiers) != RequiredModifiers){ Report.Error ( 558, Location, "User defined operators `" + Prototype (parent) + "' must be declared static and public"); return false; } param_list[0] = new Parameter (FirstArgType, FirstArgName, Parameter.Modifier.NONE, null); if (SecondArgType != null) param_list[1] = new Parameter (SecondArgType, SecondArgName, Parameter.Modifier.NONE, null); OperatorMethod = new Method (ReturnType, ModFlags, MethodName, new Parameters (param_list, null, Location), OptAttributes, Mono.CSharp.Location.Null); OperatorMethod.IsOperator = true; OperatorMethod.Define (parent); if (OperatorMethod.MethodBuilder == null) return false; OperatorMethodBuilder = OperatorMethod.MethodBuilder; Type [] param_types = OperatorMethod.ParameterTypes; Type declaring_type = OperatorMethodBuilder.DeclaringType; Type return_type = OperatorMethod.GetReturnType (); Type first_arg_type = param_types [0]; // Rules for conversion operators if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) { if (first_arg_type == return_type && first_arg_type == declaring_type){ Report.Error ( 555, Location, "User-defined conversion cannot take an object of the " + "enclosing type and convert to an object of the enclosing" + " type"); return false; } if (first_arg_type != declaring_type && return_type != declaring_type){ Report.Error ( 556, Location, "User-defined conversion must convert to or from the " + "enclosing type"); return false; } if (first_arg_type == TypeManager.object_type || return_type == TypeManager.object_type){ Report.Error ( -8, Location, "User-defined conversion cannot convert to or from " + "object type"); return false; } if (first_arg_type.IsInterface || return_type.IsInterface){ Report.Error ( 552, Location, "User-defined conversion cannot convert to or from an " + "interface type"); return false; } if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)){ Report.Error ( -10, Location, "User-defined conversion cannot convert between types " + "that derive from each other"); return false; } } else if (SecondArgType == null) { // Checks for Unary operators if (first_arg_type != declaring_type){ Report.Error ( 562, Location, "The parameter of a unary operator must be the " + "containing type"); return false; } if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) { if (return_type != declaring_type){ Report.Error ( 559, Location, "The parameter and return type for ++ and -- " + "must be the containing type"); return false; } } if (OperatorType == OpType.True || OperatorType == OpType.False) { if (return_type != TypeManager.bool_type){ Report.Error ( 215, Location, "The return type of operator True or False " + "must be bool"); return false; } } } else { // Checks for Binary operators if (first_arg_type != declaring_type && param_types [1] != declaring_type){ Report.Error ( 563, Location, "One of the parameters of a binary operator must " + "be the containing type"); return false; } } return true; }