C# MarshalByRefObject 和Serializable的區別


這兩種方式的類一般都是用於遠程傳輸時使用。

marshalbyrefobject是通過引用傳遞serializable是通過值傳遞,現在就來分析下什么是引用傳遞,什么是值傳遞。

理解這個對Remoting或者webservice的認識是很重要的。

marshalbyrefobject(引用)本機或者是服務器上的其實都是同一個實例,只不過是服務器創建后你在本地使用了那個對象而已。比如說A類繼承了marshalbyrefobject那么A類由服務器創建實例了,客戶端都可以使用這個實例了。

現在我們假設A類有一個方法叫着A,Function返回值為一個string類型這個方法有一系列的操作。客戶端在調用這個方法的時候只得到服務器返回的一個值,那個一系列的操作都將在服務器完成,這就是所謂的餿客服端。

Serializable(值類型)這個就不同了,假定我們剛才的那個A類的Funciton方法需要一個B類作為參數,B是一個可序列化的類,也就是類的定義上面加了[Serializable()],如果沒加那么這個方法將會報錯。我們通過一個remoting的例子來解釋一下

先寫一個繼承marshalbyrefobject的類

 public class HelloServer : MarshalByRefObject
    {
        public HelloServer()
        {            Console.WriteLine("HelloServer activated");        }


        public String HelloUserMethod(User user)
        {
            string title;
            if (user.Male)
                title = "先生";
            else
                title = "女士";

            Console.WriteLine( "Server Hello.HelloMethod : 你好,{0}{1}",  user.Name,title);

            return "你好," + user.Name + title;
        }

    }

再寫一個可序列化的類

[Serializable]
 public class User
 {
  public User(string name,bool male)
  {
            this.name = name;
            this.male = male;
  }
  string name="";
  bool male=true;
  public string Name
  {
   get{return name;}
   set{name = value;}
  }
  public bool Male
  {
   get{return male;}
   set{male = value;}
  }

 }

現在我們將在服務端和客戶端使用它們。

服務端如下:

 public class Server
 {
  public static int Main(string [] args) 
  {

   TcpChannel chan1 = new TcpChannel(8085);
   HttpChannel chan2 = new HttpChannel(8086);

   ChannelServices.RegisterChannel(chan1);
   ChannelServices.RegisterChannel(chan2);


RemotingConfiguration.RegisterWellKnownServiceType (typeof(HelloServer), "SayHello", WellKnownObjectMode.Singleton);   //創建類的實例

   System.Console.WriteLine("Press Enter key to exit");
   System.Console.ReadLine();
   return 0;
  }

客戶端如下:

public class Client
 {
        public static void Main(string[] args)
        {
          //使用HTTP通道得到遠程對象
            HttpChannel chan2 = new HttpChannel();
            ChannelServices.RegisterChannel(chan2);
            HelloServer obj1 = (HelloServer)Activator.GetObject(
                typeof(RemotingSamples.HelloServer),
                "http://localhost:8086/SayHello");//創建類的實例
            if (obj1 == null)
            {
                System.Console.WriteLine(
                    "Could not locate HTTP server");
            }
            Console.WriteLine(
                "Client1 TCP HelloUserMethod {0}",
                obj1.HelloUserMethod(new User("張生",true))); //將類作為參數
(將User作為參數必須是serializable)                   }

 }

 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM