2014-02-07 40 views
3

假設你有定義爲WCF可以通過線路保持引用相等嗎?

[DataContract] 
public class Foo 
{ 
    [DataMember] 
    public List<Bar> Bars {get; set;} 
} 

[DataContract] 
public class Bar 
{ 
    [DataMember] 
    public string Baz { get; set; } 
} 

public class Service1 : IService1 
{ 
    public bool Send(Foo foo) 
    { 
     var bars = foo.Bars; 

     bars[0].Baz = "test2"; 
     return bars[0].Baz == bars[1].Baz; 
    } 
} 

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    bool Send(Foo composite); 
} 

假設我幾節課我使用WCF與客戶端和服務器之間共享數據合同DLL到WCF,如果我這樣做了以下

static void Main(string[] args) 
{ 
    using (var client = new ServiceReference.Service1Client()) 
    { 
     var bar = new Bar(); 
     bar.Baz = "Start"; 

     List<Bar> bars = new List<Bar>(); 
     bars.Add(bar); 
     bars.Add(bar); 

     var foo = new Foo(); 
     foo.Bars = bars; 

     Console.WriteLine(bars[0].Baz == bars[1].Baz); 

     bars[0].Baz = "test1"; 
     Console.WriteLine(bars[0].Baz == bars[1].Baz); 

     Console.WriteLine(client.Send(foo)); 

     Console.ReadLine(); 
    } 

} 

我得到True,True,False作爲我的結果,這意味着bars[0]bars[1]沒有指向服務器上的同一個對象。

我做錯了什麼,或者不可能通過WCF共享引用?

回答

4

通過指定

[DataContract(IsReference = true)] 

否則引用消息施工過程中的平等丟失得explicitly tell WCF to preserve references

+0

我需要做什麼才能使上面的代碼使用'BinaryFormatter'? –

+0

我不知道如何使用'BinaryFormatter'而不用自己嘗試。但是你可以 - 如果你還沒有 - 嘗試使用'BinaryMessageEncoding',這可能會保持引用的平等,但我不知道。 –

+0

我錯了,這是行不通的,因爲WCF首先生成一條消息,然後才使用指定的序列化程序對其進行序列化。但是此時默認情況下引用已經丟失,因此使用引用保留序列化程序將無濟於事。但是仍然有一個解決方案,您可以指示WCF在構建消息時保留引用 - 請參閱更新後的答案。 –

2

DataContact註釋表示序列化。也就是說,你的對象被序列化,通過電線傳遞,然後在另一端重新構成一個新的對象。所以不,不可能保持參考平等。

請注意,也可能是,您的WCF服務運行在不同的機器上,或者至少是一個不同的進程。因此,WCF服務和客戶端通常甚至不能訪問相同的內存空間,這意味着在它們之間共享一個引用在理論上是不現實的。

+0

你用這種方式表達我可以使用[DataContract]以外的東西來做到這一點。我需要做些什麼呢?編輯:根據你最近的更新,我不關心客戶端和服務器共享引用,我想要的是在同一消息中發送的兩個對象仍然在另一側顯示引用相等。 –

+0

@ScottChamberlain不,因爲它必須以一種或另一種方式序列化 - 這是對象可以傳遞給另一端的唯一方式。 – McGarnagle

+0

@ScottChamberlain換個說法,如果沒有序列化,那麼就不需要WCF了 - 你可以傳遞客戶端對內存地址的引用。 – McGarnagle

相關問題