C# Mapping for Parameters and Return Values
In Parameters
An in parameter is mapped to a C# parameter with the same name; its type is the mapped C# type.
For example, a Slice parameter string name is mapped to a C# parameter string name.
Out Parameters in Synchronous Methods
An out parameter is mapped to an out parameter with the same name in synchronous proxy and skeleton methods; the type of the parameter is the mapped C# type.
Consider the following example:
struct NumberAndString
{
int x;
string str;
}
sequence<string> StringSeq;
dictionary<long, StringSeq> StringTable;
interface ServerToClient
{
["cs:identifier:Op1"]
void op1(out int i, out float f, out bool b, out string s);
["cs:identifier:Op2"]
void op2(out NumberAndString ns, out StringSeq ss, out StringTable st);
["cs:identifier:Op3"]
void op3(out ServerToClient* proxy);
}
The Slice compiler generates a proxy interface for these definitions (we omit the async overloads):
public partial interface ServerToClientPrx : Ice.ObjectPrx
{
void Op1(
out int i,
out float f,
out bool b,
out string s,
Dictionary<string, string>? context = null);
void Op2(
out NumberAndString ns,
out string[] ss,
out Dictionary<long, string[]> st,
Dictionary<string, string>? context = null);
void Op3(
out ServerToClientPrx? proxy,
Dictionary<string, string>? context = null);
}
Return Values in Synchronous Methods
A Slice return value is mapped to a C# return value in synchronous proxy and skeleton methods.
Out Parameters and Return Values in Asynchronous Methods
Out parameters and return values are mapped to C# Task return values.
The returned Task depends on how many values an operation returns, including out parameters and a non-void return value:
Zero values
The corresponding C# method returns a plainTask.One value
The corresponding C# method returns aTask<T>, where T is the mapped C# type.Two or more values
The corresponding C# method returns aTask<Interface_OpResult>, whereInterface_OpResultis a generated record struct that holds the return value and out parameters.
Consider this example:
interface Example
{
["cs:identifier:Op"]
double op(int inp1, string inp2, out bool outp1, out long outp2);
}
The Slice compiler generates the following C# code for this interface:
public record struct Example_OpResult(double returnValue, bool outp1, long outp2);
public partial interface ExamplePrx : Ice.ObjectPrx
{
Task<Example_OpResult> OpAsync(
int inp1,
string inp2,
Dictionary<string, string>? context = null,
...);
}
Optional Parameters
The mapping for optional parameters is the same as for required parameters, except each mapped C# type is nullable, where null represents “not set”.
Consider the following operation:
["cs:identifier:Execute"]
optional(1) int execute(optional(2) string parameters, out optional(3) float value);
The corresponding C# proxy method is:
// Asynchronous variant
Task<Example_ExecuteResult> ExecuteAsync(
string? parameters,
Dictionary<string, string>? context = null, ...);
and the corresponding C# skeleton method is:
// Synchronous variant
int? Execute(string? parameters, out float? value, Ice.Current current);