這兩種方式的類一般都是用於遠程傳輸時使用。
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) }
}
}