2017-06-06 68 views
0

免責聲明調用方法:不專業的開發商C# - 轉換而與輸出參數

我們使用SSIS拉消息RabbitMQ的,我已經成功地構建拉和彈出消息了我們一個C#腳本組件排隊給我們使用Queue.Dequeue()。到現在爲止還挺好。但是,我們希望進行某種形式的自動檢查,以便我們的SSIS組件不會連續運行,而是可以計劃每n分鐘運行一次。

我發現這個方法Dequeue(int timeout, out object result),並已成功地實現它,像這樣:(我們想要的BasiocDeliverEventArgs導致以處理郵件的正文)

object message; 
myConsumer.Queue.Dequeue(millisecondsTimeout: 500, result:out message); 
BasicDeliverEventArgs ea = (BasicDeliverEventArgs)message; 

這似乎是工作,但不知何故,我覺得有點多餘。例如,這對我來說似乎更直觀:

myConsumer.Queue.Dequeue(millisecondsTimeout: 500 
    , result:out (BasicDeliverEventArgs)message) 

但是,這會產生一個指定無效參數的錯誤。有人能解釋爲什麼它會拋出這個錯誤,爲什麼這個語法是無效的?

+1

因爲C#語言規範是這樣說的。 –

+1

類型化隊列不會更有幫助嗎? –

+0

@PatrickHofman什麼是類型化隊列?只是搜索它,但我沒有立即看到任何解釋更多。至於先前的評論,夠公平的。我希望找到解釋爲什麼會這樣說。 – SchmitzIT

回答

1

Dequeue方法在第二個參數中接受object類型。但你傳遞給它一個BasicDeliverEventArgs類型。這就是你遇到錯誤的原因。如果隊列中有EmployeeSomeotherType,該方法將無法將其分配給BasicDeliverEventArgs引用。

該方法返回後,調用方將其轉換爲該方法。

而且從MSDN讀這句話:

out關鍵字使得通過引用傳遞參數。它就像ref關鍵字一樣,只是ref需要變量在傳遞之前被初始化。要使用out參數,無論是方法定義和調用方法必須明確地使用了關鍵字

在C#中幾乎所有繼承object所以你所謂的可以存儲在一個object引用任何類型(只要方法他們繼承對象)並將其返回給您。然而,它不能在BasicDeliverEventArgs參考中存儲任何類型,這就是爲什麼它不允許它。

2

你不能做到這一點:

myConsumer.Queue.Dequeue(millisecondsTimeout: 500 
, result:out (BasicDeliverEventArgs)message) 

因爲Dequeue方法允許分配任何objectmessage參數 - 它可能是一個"string",等等 - 這將導致VeryBadThings™。

所以不:你不能那樣做。

+1

'VeryBadThings™'代表什麼?^^ – NtFreX

+0

儘管如此,編譯器理論上可以在方法之後/期間將Dequeue()的「object」賦值給調用者參數。這將是一個巨大的混亂範圍等 –

+0

@HenkHolterman這也將是''ref'等''覆蓋實現的很多爛攤子 - 導致更多細微的情況下的後果 –