2016-06-13 15 views
0

我有一個對象列表(它們的類型未提前未知)。下面的例子顯示了硬編碼值,但是我的實際代碼通過從CSV文件中讀取來填充參數列表。然後我想將這個參數列表傳遞給請求某些參數的典型方法。所以我將元素轉換爲所需的類型,如圖所示。我得到錯誤:將一個對象變量傳遞給方法 - 指定的轉換無效

Specified cast is not valid

當在運行時調用該方法。我應該如何去做到這一點?

var args = new List<object>(); 
     args.Add(5495); 
     args.Add("String1"); 
     args.Add(10133); 
     args.Add("String2"); 

     result = request.GetCustomer((long) args[0], (string) args[1], (int) args[2], (string) args[3]); 
+1

該錯誤明確告訴你爲什麼你不能執行轉換,包括對象的實際類型以及要轉換的對象。如果您希望在運行時不失敗,您需要將對象轉換爲* actual *類型。 – Servy

+0

好吧,一個好的開始將是圍繞這個和一個計數的try catch塊,以便您可以看到csv中的哪一行是罪魁禍首。 – Kell

+0

@Kell一個'try' /'catch'塊只會掩蓋問題。他已經可以看到這個錯誤,他只需要修正他的代碼中的錯誤。 – Servy

回答

4

當您添加值類型List<object>()

args.Add(5495); 

,該項目將Boxed。上面的行導致5495int被裝箱。要開箱,您需要明確地將args[0]轉換爲其類型爲 - (int)args[0]。因此,如果您的方法接受long作爲其第一個參數,請執行(long)(int)args[0]。您拆箱args[0],然後將值轉換爲long

+1

中找到一些額外的信息,謝謝你!這解決了這個問題,我實際上意識到我可以只將該參數強制轉換爲(int)而不是(long)。 – AngieM

1

問題是5495將有一個int類型,並且您試圖將其強制轉換爲long。你可以通過幾種方式來解決這個問題,下面是其中之一。

替換此;

(long) args[0] 

與此;

(long) (int) args[0] 

這不會是一個非常有用的解決方案然而,因爲你永遠無法真正通過你的方法很值,而不是你能做到這一點;

args.Add((long) 5495); 
0

嘗試使用轉換。一changeType

 var args = new List<object>(); 
     args.Add(5495); 
     args.Add("String1"); 
     args.Add(10133); 
     args.Add("String2"); 


     long aLong = (long)Convert.ChangeType(args[0], typeof(long), CultureInfo.InvariantCulture); 

     string aStr = (string)Convert.ChangeType(args[1], typeof(string), CultureInfo.InvariantCulture); 

     int aInt = (int)Convert.ChangeType(args[2], typeof(int), CultureInfo.InvariantCulture); 
0

創建商店列表數據

類測試{

私人長期變量1 {獲得單獨的類;集;}

私人字符串變量2 {獲取;集;}

private long Variable3 {get; set;}

私人字符串Variable4 {獲取;集;}

}

變參=新名單();

VAR OBJ =新測試{

變量1 = 5495,

變量2 = 「String1中」,

Variable3 = 10133,

Variable4 = 「String2的」

}

args.add(obj);

result = request.GetCustomer(args [0] .Variable1,args [0] .Variable2,args [0] .Variable3,args [0] .Variable4);

0

讓我們簡化一下這個問題。

var args = new List<object>(); 
args.Add(5495); 
var l = (long)args[0]; // throws an exception 

args [0]裏面究竟是什麼?一個int(因爲5495是編譯器的一個int,如果你希望它是一個很長的類型5495L)。更確切地說,一個盒裝int,因爲你必須將其存儲在參考類型的存儲位置。盒裝結構只能拆箱到相同的結構或可結構爲空的結構。在我們的情況下,

var i = (int)args[0]; 
var nullable = (Nullable<int>)args[0]; 
var nullable1 == (int?)args[0]; 

都會正常工作。

雖然已將其拆箱,但您可以將其值轉換爲任何兼容的值。

您可以在msdn上閱讀更多關於拳擊和拆箱的信息。如果你想高效地使用C#,這是非常寶貴的理解。

你的問題的根本原因是你使用List<object>雖然,使拳擊不可避免的。這是非常罕見的,你真的需要這樣做,你應該認爲你的架構可以避免它。

+0

感謝您關於拳擊/拆箱(尤其是表演)的推薦閱讀。我是一個小菜鳥。是的,這個設計可能並不理想。我必須爲每個參數調用20-30個參數的不同方法,所以我厭倦了爲每種方法定義20-30個變量 - >對象列表。如果你對我的情況有更好的建議,我會全力以赴。謝謝! – AngieM

+0

20-30參數*很多*。任何理智的方法都不應該有那麼多。您應該重構大部分那些在您的業務邏輯中有意義的自定義類,並將這些對象的幾個傳遞給您的方法。 – Falanwe

+0

這些主要是創建特定類型數據的Web服務方法(例如公司擁有大量關於公司的數據的公司記錄)。是的,當我走時,我可能會重構一些常見的領域。 – AngieM