• 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 引用、还是通过空串发送串,对接收者都没有区别;不管是哪种方式,接收者看到的都是空串。

  • 相关阅读:
    mysql The server time zone value 'xxx' is unrecognized
    mysql Public Key Retrieval is not allowed
    mysql Unable to load authentication plugin 'caching_sha2_password'.
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
  • 原文地址:https://www.cnblogs.com/zhangronghua/p/1203773.html
Copyright © 2020-2023  润新知