ICE框架之Slilce2CSharp映射---操作的映射

对于接口上的每个操作,代理类都有一个对应的同名成员函数。要调用某个操作,你要通过代理调用它。例如,下面给出的文件系统的部分定义 :

         module Filesystem {
             interface Node {
                 nonmutating string name();
             };
             // ...
         };

name操作返回的是类型为 string 的值。假定我们有一个代理,指向的是Node 类型的对象,客户可以这样调用操作:

         NodePrx node = ...;             // Initialize proxy
         string name = node.name();      // Get name via RPC

这是典型的返回值接收模式:对于复杂的类型,返回值通过引用返回,对于简单的类型 (比如 int或 double)则直接返回值。。

普通的、idempotent,以及nonmutating操作

你可以给 Slice 操作增加 idempotent 或nonmutating 限定符。就对应的代理方法的签名而言,idempotent或nonmutating没有任何效果。例如,考虑下面的接口:

         interface Example {
                         string op1();
             idempotent  string op2();
             nonmutating string op3();
         };

这个接口的代理类是:

         public interface ExamplePrx : Ice.ObjectPrx {
            String op1();
            String op2();
            String op3();
         }

因为idempotent和nonmutating影响的是调用分派(call dispatch )、而不是接口的某个方面,这三个方法看起来一样,是有道理的。

参数传递

in 参数

C# 映射的参数传递规则非常简单:参数或者通过值传递 (对于值类型),或者通过引用传递 (对于引用类型)。在语义上,这两种传递参数的方式是等价的:调用保证不会改变参数的值 (XREF 给出了一些警告)。
下面的接口有一些操作,会把各种类型的参数从客户传给服务器:

         struct NumberAndString {
             int x;
             string str;
         };

         sequence<string> StringSeq;

         dictionary<long, StringSeq> StringTable;

         interface ClientToServer {
             void op1(int i, float f, bool b, string s);
             void op2(NumberAndString ns, StringSeq ss, StringTable st);
             void op3(ClientToServer* proxy);
         };

Slice 编译器为这个定义生成这样的代码:

         public interface ClientToServerPrx : Ice.ObjectPrx {
             public void op1(int i, float f, boolean b, String s);
             public void op2(NumberAndString ns,
                             StringSeqss,
                              StringTable st);
             public void op3(ClientToServerPrx proxy);
         }

假定我们有一个代理,指向的是ClientToServer接口,客户代码可以这样传递参数:

         ClientToServerPrx p = ...;               // Get proxy...

         p.op1(42, 3.14f, true, "Hello world!"); // Pass simple literals

         int i = 42;
         float f = 3.14f;
         boolean b = true;
         String s = "Hello world!";
         p.op1(i, f, b, s);                       // Pass simple variables  

NumberAndString ns = new NumberAndString();
          ns.x = 42;
          ns.str = "The Answer";
          StringSS ss = new StringSS():
ss.Add(“hello world”);
StringTable st = new StringTable();
st[0] = ns;
          st.put(new Long(0), ns);
          p.op2(ns, ss, st);                       // Pass complex variables

          p.op3(p);                                // Pass proxy

out 参数

slice out 参数直接映射成为C# out参数。

下面是我们在前面看到过的Slice定义,但所有的参数都是作为out 参数传递的:

          struct NumberAndString {
              int x;
              string str;
          };

          sequence<string> StringSeq;

          dictionary<long, StringSeq> StringTable;

          interface ServerToClient {
              void op1(out int i, out float f, out bool b, out string s);
              void op2(out NumberAndString ns,
                       out StringSeq ss,
                       out StringTable st);
              void op3(out ServerToClient* proxy);
          };

Slice 编译器为这个定义生成了以下代码:

public interface ServerToClientPrx : Ice.ObjectPrx

{

void op1(out int i, out float f, out bool b, out string s);

void op2(out NumberAndString ns,

out StringSeq ss,

out StringTable st);

void op3(out ServerToClientPrx proxy);

}    

假定我们有一个代理,指向的是 ServerToClient接口,客户代码可以这样传递参数:

      ClientToServerPrx p = ...; // Get proxy...

int i;

float f;

bool b;

string s;

p.op1(out i, out f, out b, out s);

NumberAndString ns;

StringSeq ss;

StringTable st;

p.op2(out ns, out ss, out st);

ServerToClientPrx stc;

p.op3(out stc);

System.Console.WriteLine(i); // Show one of th

Null 参数

有些 Slice 类型自然地就有 “空”或 “不存在”语义。比如,C#序列(如果映射到CollectionBase)、字典,以及串和结构(如果映射到Class)都可以为null,但它们对应的slice定义却没有空值这个概念:
* Slice序列、字典、string不能为 null,但可以是空的。为了让这些类型的使用更容易,只要你把C# null 引用用作序列、字典、字符串的参数或返回值,Ice run time 都会自动把空的序列、字典、字符串发给接收者。
*当slice结构映射到C#类时,这时如果你传递一个空引用作来结构的参数或是返回值,ice run time自动将其转化为一个包含默认值的结构,这意味着所有代理成员都被初始为null,序列和字典成员被初始为空集合,字符串成员被初始化为空串,如果还有值类型的成员的,则会被初始化为它们对应的初始值。

作为一种方便的特性,这种行为很有用,特别是对于很深地嵌套的数据类型,其成员中的序列、字典,或字符串会自动作为空值到达接收端,例如,这样一来,在把一个大序列发送出去之前,你无需显式地初始化每一个串元素,也不会产生NullPointerExceptions。注意,以这种方式使用 null 参数并没有为序列、字典,或串创建null 语义。就对象模型而言,它们的 null 语义并不存在 (存在的只是空的序列、字典,以及串)。例如,不管你是通过null 引用、还是通过空串发送串,对接收者都没有区别;不管是哪种方式,接收者看到的都是空串。

原文地址:https://www.cnblogs.com/zhangronghua/p/1203773.html