Skip to main content

Unqualified References

A SAL expression can identify a member without naming its declaring object explicitly. Some forms are resolved from runtime window context. C# requires an object and a member that its compiler can resolve, or an explicit runtime lookup. Ice Porter chooses between those approaches according to the information available during conversion.

The key question is not just which member name, but which open instance owns it. Qualifying an expression can remove a compiler ambiguity while still selecting the wrong form instance.

Fully Unqualified​

Consider an assignment made outside the form that declares the control:

Set dfAge = 20

If conversion finds dfAge in only one relevant form template, it can qualify the expression through that template's generated application reference:

App.frmPatient.dfAge.Number = 20;

This is a representative desktop generation pattern. It assumes the template reference identifies the intended live frmPatient instance. The name does not create a form or select an arbitrary patient's open window for you.

If the name occurs in several templates and there is no usable runtime owner, the converter cannot safely choose one. Resolve the conversion diagnostic by identifying the intended object; do not choose the first matching field merely to obtain a successful build.

Class Qualified​

A handle plus a class/template qualification supplies more information:

Set hWnd.frmPatient.dfAge = 20

The generated expression can convert the handle to the expected form type and access the member. Depending on generator options, the shape may use a cast or a generated helper:

((frmPatient)hWnd).dfAge.Number = 20;
// Alternative generated style:
frmPatient.FromHandle(hWnd).dfAge.Number = 20;

These are alternative expressions, not two assignments to perform. When the qualified owner is known to be the current instance, Ice Porter can sometimes use this directly.

A cast or FromHandle call does not prove the handle is valid, still alive, or of the requested type. Use the generated helper's actual signature and failure behavior. A handle to another form is not repaired by adding the desired class name to the expression.

Handle Semi-qualified​

A handle-qualified expression names the runtime owner but leaves its type implicit:

Set hWnd.sName = "PPJ"

Where the type cannot be selected statically, generated code can preserve the dynamic lookup:

SalWindow.FindMember(hWnd, "sName").String = "PPJ";

Here the handle selects the object; the string selects its member; and .String accesses the string value through PPJ's member wrapper. The lookup is not a C# string-indexed property on the form itself.

Ambiguous Unqualified References​

Distinguish an ambiguous name with an owner from an ambiguous name without one:

Name + known type and instance → direct member access
Name + runtime handle → runtime lookup on that handle
Name only + several owners → resolve conversion ambiguity

A runtime lookup can help when the expression carries enough context to identify an owner. It cannot determine which customer's window the business operation meant if that information was never supplied.

Rename or replace dynamic references only after finding every use, including SQL bind strings, scripts, report input expressions, and generated wrappers. Renaming a C# field does not automatically update a string interpreted later.

Runtime Validation​

Test the access with the expected form open, after it has closed, and with two instances of the same form. Include an invalid handle, an unexpected form type, and a missing/renamed member. For Web, repeat the test in independent sessions.

In new code, prefer passing the intended instance or value explicitly when SAL's dynamic lookup is no longer required. Keep legacy lookups when their context-dependent behavior is intentional, and document the owner they expect. See Form Template References and SqlContext.