METHOD-ENDMETHOD
WTSupported in traditional Synergy on Windows
|
WNSupported in Synergy .NET on Windows
|
USupported on UNIX
|
VSupported on OpenVMS
|
[access] [method_mod ...] METHOD name[<T[(constraints)], ...>], return_type[, options] parameter_def [constructor_init ([arguments])] . . . PROC . . ;Method implementation . ENDMETHOD|END
Arguments
access
(optional) One of the following access modifiers:
Access is not restricted. This is the most accessible option.
Access is limited to the containing class or types derived from the containing class.
Access is limited to the containing type. This is the least accessible option. (default)
Access is limited to the current assembly. (Synergy .NET only)
Access is limited to the current assembly and types derived from the containing class. (Synergy .NET only)
method_mod
(optional) One or more of the following modifiers, with the restrictions stated in the Discussion:
Must have a method implemented in a derived class of the same signature. Subclasses must implement this method.
Method will perform asynchronous processing. See Asynchronous processing (.NET). (Synergy .NET only)
Indicate the return value is a reference. (Synergy .NET only)
Extend the functionality of a type using a static method.
Hide an inherited member of the same name.
Override the parent class’s virtual method that has the same method signature.
Method is a partial method. The return_type must be VOID. (Synergy .NET only)
Indicates the return is read-only. (Synergy .NET only)
Cannot be overridden any further by inheriting classes without the NEW keyword.
Accessed without a reference object. The method can be executed even if the class that contains the method hasn’t been instantiated.
Cannot be overloaded, overridden, or redeclared. (Unlike subroutines and functions, methods are not implicitly unique.)
More than the declared number of arguments can be passed to this routine.
Can be overridden in a subclass.
name
The name of the method to define. If you are using interfaces on .NET, this name can have the format interface.name.
T
A generic type parameter, which indicates the method is a generic method and which acts as a placeholder for which an actual type will be substituted when the member is used. Note that you can use any unused letter (not just T). See Generic types (.NET) for more information. (Synergy .NET only)
constraints
One or more of the following constraints:
- A base class, to stipulate that the generic type parameter must inherit from that specific base class. If no base class is specified, the default is System.Object.
- One or more interfaces, to stipulate that the generic type parameter must implement the specified interfaces.
- A constructor, to allow creating an instance of the type parameter using the NEW syntax.
Multiple constraints must be separated by commas. See Constraints for more information. (Synergy .NET only)
return_type
The return type of the method being defined. See Where data types can be used for the data types that are valid return types.
options
(optional) One of the following options:
Use rounding rules for implied-decimal data types within the function.
Use truncation rules for implied-decimal data types within the function. (traditional Synergy only)
parameter_def
The definition of an parameter that is unique within this method. Each parameter definition has the syntax that’s described in Defining a parameter.
constructor_init
(optional) One of the following initializers:
Run the parent class constructor next higher in the class hierarchy.
Run the current class constructor of a different signature.
arguments
(optional) One or more argument values to the constructor initializer. This value must be a literal, a STATIC field value, a CONST field value, or an argum ent name from the constructor.
By default, a method cannot be overridden unless it is marked as ABSTRACT, OVERRIDE, or VIRTUAL. (ABSTRACT and OVERRIDE methods are also assumed to be virtual and are mutually exclusive.) A method defined with one of these modifiers is called a virtual method. An ABSTRACT method has no implementation, which means it has a PROC and an END with no intervening statements. The method in the derived class that is overriding the method in the parent class must also be marked as OVERRIDE.
A BYREF method must return a BYREF parameter, a BYREF local data field, or another BYREF method call, and that entity’s return type must be exactly the same as the BYREF method return type, with no conversions. It can’t return void, descriptors, or non-CLS types, and you can’t MRETURN a value to a method marked as BYREF. In addition, BYREF can’t be used in conjunction with the ASYNC modifier or YIELD iterators.
The READONLY modifier can only be specified in conjunction with the BYREF modifier and enables the method to return a non-modifiable reference. READONLY ensures a method’s return value can only be used in read-only scenarios—it can’t be passed as a writable argument to another method.
The SEALED modifier can only be specified in conjunction with the OVERRIDE modifier.
The EXTENSION modifier can only be specified in conjunction with the STATIC modifier. It enables you to extend a class (local or in another assembly in .NET), even if the class is declared as SEALED. An extension method must be declared in a non-generic, static class, and the first parameter type should be of the type you want to extend. The first parameter type cannot be a group, and in Synergy .NET, it cannot be a non-CLS structure.
To use an extension method, you’ll need to import the namespace that contains the class that contains the extension method and then call it using an instance of the first parameter of the extension method. (See Examples.) The class members you are using must be public. If an extension method has the same signature (minus the first parameter of the extension method) as an existing method in the class, the compiler resolves to the existing class method.
You can hide a class member in a parent class with an identical signature in an inherited class by specifying a member with the same name, along with the NEW member modifier, within the inheriting class. You can also hide dissimilar members. (For example, a field or a sealed member in the parent can be hidden by a method or field of the same name marked NEW in the child.)
The class members can be different kinds (for example, a method and a field).
In Synergy .NET, a partial class can contain a partial method, which is specified with the PARTIAL modifier. A partial method declaration consists of two parts: the definition and the implementation. These can be in separate parts of a partial class or in the same part. If none of the partial methods has an implementation, any calls to the method will be ignored. A partial method must also have at least one declaration without an implementation, or a MISDECL error is reported.
Partial methods enable the implementer of one part of the class to define a method, while the implementer of the other part of the class determines whether or not to implement the method. Partial methods must be private, must return VOID and can’t be virtual. Parameters to partial methods can’t have an OUT attribute.
The VARARGS modifier is required if you want to permit passing additional, nondeclared arguments. We recommend that you don’t use VARARGS on methods.
In the table below, a check mark indicates that the two modifiers can be used in the same method definition
Modifier |
ABSTRACT |
ASYNC |
EXTENSION |
NEW |
OVERRIDE |
PARTIAL |
SEALED |
STATIC |
UNIQUE |
VARARGS |
VIRTUAL |
---|---|---|---|---|---|---|---|---|---|---|---|
ABSTRACT |
|
|
|
||||||||
ASYNC |
|
|
|
|
|||||||
EXTENSION |
|
||||||||||
NEW |
|
|
|
|
|
|
|||||
OVERRIDE |
|
|
|
||||||||
PARTIAL |
|
||||||||||
SEALED |
|
|
|||||||||
STATIC |
|
|
|
|
|
|
|||||
UNIQUE |
|
|
|
|
|||||||
VARARGS |
|
|
|
|
|
|
|
||||
VIRTUAL |
|
|
|
||||||||
PRIVATE |
|
|
|
|
|
|
|
|
|
||
INTERNAL |
|
|
|
|
|
|
|
|
|
|
|
PROTECTED |
|
|
|
|
|
|
|
|
|
|
|
PUBLIC |
|
|
|
|
|
|
|
|
|
|
When used in an interface in a .NET Core or .NET 5 and higher project, the following modifiers are supported: PUBLIC, PRIVATE, PROTECTED, INTERNAL, SEALED, ABSTRACT, and VIRTUAL.
All defined methods are reentrant, and method data is stack based.
A program by default rounds all expression results. You can change the default to truncate in traditional Synergy by setting system option #11. However, specifying the ROUND or TRUNCATE option on a METHOD statement overrides the default rounding behavior for that function (including if system option #11 is set). You cannot specify both TRUNCATE and ROUND in the same statement. (Neither TRUNCATE nor system option #11 are supported in Synergy .NET.)
The method name (name) cannot be any of the following reserved keywords: new, parent, or value (for a property set method). Also be careful when using any other Synergy DBL keywords, such as the names of I/O statements; if the method signature coincidentally matches that of the statement with the same name, the statement will be assumed.
Asynchronous processing (.NET)
.NET Framework 4.5 and higher, .NET Core, and .NET 5 and higher support asynchronous processing.
The ASYNC modifier indicates that the method will perform asynchronous processing, which means that a process can occur independently of other processes instead of being required to occur in direct succession. The method can return immediately without blocking the calling thread.
Within an asynchronous method, you must specify one or more AWAIT statements, which wait for the corresponding asynchronous task to complete. If you don’t include an AWAIT statement, your ASYNC method will not be asynchronous, because an ASYNC method does not run on its own thread.
An ASYNC method doesn’t return to its original caller until it gets to the first AWAIT statement and waits for a task that isn’t yet complete. Therefore, you should use ASYNC methods for tasks that don’t require very much thread time, and they should not perform blocking calls before their first AWAIT statement or between AWAIT statements.
An ASYNC method can contain any variable currently in scope, with the following exceptions:
- Fields that are in a group, in a named record, or overlayed
- Parameters that are BYREF, OUT, INOUT, in a group, or a parameter group
Return_type must be void, Task, or Task<>. After an AWAIT expression is fully processed, a subsequent RETURN statement completes a previously returned Task<> with a final result.
A method can be both asynchronous and an iterator block, meaning an AWAIT statement and a YIELD statement can both be present in the procedure division of that method. The return type of a method that is both ASYNC and YIELD should be IAsyncEnumerable<T>, which represents an asynchronous collection.
Declaring constructor and destructor methods
You can optionally declare one or more constructor methods for a class by giving the constructor methods the same name as the class. Arguments are allowed on constructor methods to make the method signatures of the constructors unique.
You can also declare a single destructor for a class by giving the method the same name as the class with a tilde (~) appended to the beginning. See Constructors and destructors for more information.
Method implementation
You can return from a method that has a declared return type using the MRETURN statement.
See also
In the example below, a method called writeit is defined.
public method writeit, void c2, @class2 proc open(1,o,"tt:") writes(1,"num="+%string(c2.m_number)) close(1) mreturn endmethod
The example below declares an extension method called WordCount and calls it using an instance of the first parameter of the method:
namespace MyExtensions public static class MyExtensionClass public extension static method WordCount, int Parm1, string proc <method body> end import MyExtensions main record str, string x, int proc x = str.WordCount()
The example below asynchronously gets the page titles from www.weather.gov and www.synergex.com.
public async method clickit, void record wc, @WebClient uri, @Uri uri2, @Uri uri3, @Uri proc listBox1.Items.Add("before"); wc = new WebClient() uri = new Uri("http://www.weather.gov"); WriteLinePageTitle(await wc.DownloadStringTaskAsync(uri)) listBox1.Items.Add("between"); uri2 = new Uri("http://www.synergex.com"); WriteLinePageTitle(await wc.DownloadStringTaskAsync(uri2)) listBox1.Items.Add("after"); endmethod
The following example declares a partial class and partial method:
namespace ns1 public partial class class1 public static partial method meth1, void proc Console.WriteLine("meth1"); endmethod endclass endnamespace
The example below returns a reference to the first parameter:
public static byref method myval, int
byref parm1, int
proc
mreturn parm1
end
Using this value, we can also define a local variable that is also a reference (by adding BYREF before DATA on a local data field):
data ivar, int, 8 byref data iref, int iref = ns1.class1.myval(ivar) Console.WriteLine(iref);
In this example, the return and the local variable are both references to the location of ivar. So if we changed the value of ivar to 9 and printed out iref, we’d see 9:
var = 9; Console.WriteLine(iref);
In the example below parm1 is passed by reference, but the compiler prevents any other routines from modifying the return:
public byref readonly method meth4, @class0 in byref parm1, @class0 proc mreturn parm1; end