程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Remoting 的“傳遞的引用”理解,remoting傳遞

Remoting 的“傳遞的引用”理解,remoting傳遞

編輯:C#入門知識

Remoting 的“傳遞的引用”理解,remoting傳遞


  WCf是集大成者,具有其他微軟的很多技術,其中分布式上很多借助於Remoting,所以研究一下Remoting有助於理解WCF

  提到Remoting就不得不涉及到MarshalByRefObject這個對象,網絡上對這個詞語的解釋非常的模糊不清,特別是說“跨域訪問,Remoting是引用傳遞,不是值傳遞”,而沒有講“引用傳遞”到底是傳的什麼東西,有的地方確實說了通過ObjRef對象 傳遞需要交互的所有內容信息,但是更多的是對“引用傳遞”沒有清楚的認識,或者說是通過其他方式來理解“引用傳遞”而不是通過“引用傳遞”來更好的理解Remoting,這種邏輯思維方式,特別容易產生囫囵吞棗的模糊概念,看似明白,其實不明白。

  為了理解引用傳遞,寫了一個例子,可能有助於理解 代碼

定義Interface

public interface IPersonService
    {
        String HelloMethod(String name);
    }

定義 Implement

public class PersonService : MarshalByRefObject, IPersonService
{
    public String HelloMethod(String name)
    {
        Console.WriteLine(
            "Server Hello.HelloMethod : {0}", name);
        return "Hi there " + name;
    }
}

定義Service
static void Main(string[] args)
        {
            //TCP協議傳輸消息的信道實現
            TcpChannel chan1 = new TcpChannel(8085);
            //為遠程調用實現使用HTTP協議傳輸消息的客戶端通道
            HttpChannel chan2 = new HttpChannel(8086);
            //提供幫助進行遠程處理信道注冊、解析和URL發現的靜態方法。無法繼承此類
            ChannelServices.RegisterChannel(chan1, false);
            ChannelServices.RegisterChannel(chan2, false);
            //提供多種配置遠程結構的靜態方法
            RemotingConfiguration.RegisterWellKnownServiceType
                (
               //typeof(HelloServer),
               typeof(PersonService),
                "SayHello",
                WellKnownObjectMode.Singleton
                );


            System.Console.WriteLine("Press Enter key to exit");
            System.Console.ReadLine();
        }
定義Client
class Program
    {
        static void Main(string[] args)
        {
            TcpChannel chan1 = new TcpChannel();
            ChannelServices.RegisterChannel(chan1,false);
            //Activator包含特定的方法,用以在本地或從遠程創建對象類型、或獲取對現有遠程對象的引用。無法繼承此類
            IPersonService obj1 = (IPersonService)Activator.GetObject(
                typeof(IPersonService),// typeof(HelloServer),
                "tcp://localhost:8085/SayHello");
            if (obj1 == null)
            {
                System.Console.WriteLine(
                    "Could not locate TCP server");
            }
            //使用HTTP通道得到遠程對象
            HttpChannel chan2 = new HttpChannel();
            ChannelServices.RegisterChannel(chan2,false);
            IPersonService obj2 = (IPersonService)Activator.GetObject(
                typeof(IPersonService),// typeof(HelloServer),
                "http://localhost:8086/SayHello");
            if (obj2 == null)
            {
                System.Console.WriteLine(
                    "Could not locate HTTP server");
            }

            Console.WriteLine(
                "Client1 TCP HelloMethod {0}",
                obj1.HelloMethod("Caveman1"));
            Console.WriteLine(
                "Client2 HTTP HelloMethod {0}",
                obj2.HelloMethod("Caveman2"));
            Console.ReadLine();
        }
    }

注意,客戶端使用的 “IPersonService”接口,對於客戶端來講是不知道接口的實例類的,

客戶端方法的調用也只是通過Activator生成的代理對象把調用的信息、鏈接信息等等進行打包,

服務端接收到打包過來的信息後,根據打包信息內容,對相應的類和方法進行操作,比如:創建(調用)服務實體,對方法進行調用,把返回值進行打包並傳輸給客戶端端,裡邊具體的邏輯還需要繼續研究

這裡只想說明一點,“Remoting傳輸的引用”,到底是什麼意思,免得誤解。


值傳遞與引用傳遞的不同是什?為何說Java中只有值傳遞?面試中要怎回答?

值傳遞只是將參數復制一份而已,函數進行操作的是另一個參數,只是另一個參數的值和傳遞的參數值是相同的。
而地址傳遞是直接把參數的地址傳遞給函數,這時函數是直接對原來的參數進行操作的。所以值會變化。
至於為什麼是只有值傳遞,你可以參考一下這個網址:www.javaeye.com/topic/214404
 

C# 對於引用類型傳遞的不解

這個問題,解釋起來還有點復雜,下面我舉一些例子來說明。

首先,我們定義一個對象,來做為測試之用。
public class TestClass
{
public int Number { get; set; }
}

然後定義幾個函數,分別來看看所謂引用類型的參數傳遞

class Program
{
static void Main(string[] args)
{
TestClass test = new TestClass();
Console.WriteLine( "default: {0}", test.Number);
Function1(test);
Console.WriteLine("after Function1: {0}", test.Number);
Function2(test);
Console.WriteLine("after Function2: {0}", test.Number);
Function3(ref test);
Console.WriteLine("after Function3: {0}", test.Number);
Function4(out test);
Console.WriteLine("after Function4: {0}", test.Number);
Console.ReadKey();

}

static void Function1(TestClass obj)
{
obj.Number = 1;
}

static void Function2(TestClass obj)
{
obj = new TestClass();
obj.Number = 2;
}

static void Function3(ref TestClass obj)
{
obj = new TestClass();
obj.Number = 3;
}

static void Function4(out TestClass obj)
{
obj = new TestClass();
obj.Number = 4;
}

}

對這段代碼執行一下,我們看一下結果:

default: 0
after Function1: 1
after Function2: 1
after Function3: 3
after Function4: 4

可以看出來,只有 Function2 沒有達到我們預期的效果,為什麼呢?它不是引用傳遞的嗎?

我想這就是樓主所面臨的問題了吧

現在我們就拿這個......余下全文>>
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved