2008-11-06 99 views
1

我有一個包含兩個方法像這樣一類:C#編譯器拋出無效參數錯誤。爲什麼?

public String getFoo(Int32 a) 
{ 
    return getBar(a, "b", null); 
} 

public String getBar(Int32 a, String b, Int32 c) 
{ 
    //do something 
    return ""; 
} 

然而,當我編譯我的課,我得到兩個錯誤:

  1. 爲getBar(整型,字符串,整數的最佳重載的方法匹配)有一些無效參數
  2. 參數 '3':無法從 '<null>' 轉換爲 'INT'

我想我unders爲什麼我得到這個錯誤:編譯器在編譯時不知道 什麼是對象的實際類型。 有人可以確認我對錯誤原因是否正確或指出真實原因?

更重要的是,我可以這樣設計我的代碼嗎?如果是這樣,我需要做些什麼來修復錯誤?我這樣設計我的類的理由是因爲我不想在getFar中複製getBar中的代碼。這兩種方法基本上是一樣的,除了一個取得第三個參數。

謝謝。

+0

謝謝大家。這正是我需要知道的。我有一個關於Int32的錯誤假設,因爲我認爲它是一個從System.Object繼承的對象。喬納森的回答真的解決了這個問題。 堆棧溢出岩石! – Notorious2tall 2008-11-06 21:36:15

回答

8

在.NET中,引用類型和值類型之間有明確的概念。

引用類型是在堆上分配的對象(它將是System.Object的子類)。所有在堆棧上的是一個指向這個對象的指針。因此,存儲空指針是完全有效的。

值類型是在堆棧上分配的對象,它將是System.ValueType的子類。由於值類型位於堆棧上,所以當您將其值傳遞給函數時,會傳遞該對象的全部內容。

值類型不能爲空。

大多數C#基元類型都是值類型。字符串是實際上是引用類型的特殊類型的基元。

在.NET 2.0中,MS添加了在結構中封裝通用類型的能力,以便它可以模擬可空類型。真正發生的是,Nullable <T>結構中的邏輯正在爲你模擬一個null。

int? nullableInt = null; 
float? nullableFloat = null; 

等等

如果你不喜歡INT:

他們使用的語法快捷方式添加一個問號的類型,例如表達呢?語法,你可以隨時使用可空<SOMETYPE>

public String getBar(Int32 a, String b, Nullable<Int32> c) 

作爲一個方面說明,我寧願做你在做什麼時添加的過載,只是爲了使語法更好。

public String getBar(Int32 a, String b) 
{ 
    this.getBar(a,b,null); 
} 

public String getBar(Int32 a, String b, Nullable<Int32> c) 
{ 
} 
+0

這是一個很好的答案。我時不時地回到它。 – Notorious2tall 2009-01-17 23:16:51

1

Int32是一個值類型,這意味着null對於Int32類型的參數不是有效參數。

如果您確實需要可爲空的整數,請使用int?類型。

您看到的兩個錯誤實際上是相同的錯誤。

2

嘗試使getBar爲空的int的第三個參數。

所以,簽名是這樣的:

public String getBar(Int32 a, String b, Int32? c) 

你可以找到更多關於可空類型在.NET herehere

1

int32是int的別名,它是一個值/不可爲空的類型。對於它的可空版本,可以使用System.Nullable或簡單的'int?'。

也不要忘記轉換回一個非空的INT:

int? nullable = ...; 
int non_nullable = nullable??0; 

,其中數字表示什麼值應該承擔,如果它確實是空。

1

陽光是正確的。
Int32是一個值類型,不能包含值'null'。如果您需要將'null'作爲參數值傳遞,請使用Nullable而不是Int32作爲參數類型。

您可以在MSDN上的Nullable Types (C# Programming Guide)找到更多信息。

+0

具體來說,Int32是一個值類型,而null從來不是一個值類型的有效值。Null只對引用類型有效,它是從System.Object繼承的任何東西。 – cfeduke 2008-11-06 21:31:00

0

Int32不能爲空。使它成爲一個可空類型,而不是:

public String getBar(Int32 a, String b, Int32? c) 
{ 
    if (c.HasValue) 
    { 
     ...do something with c.Value... 
    } 
    return ""; 
} 
0

OK,所以七人提出int?的解決方案。我建議另外兩個解決方案可能更合適,這取決於具體情況;

  • 創建一個重載只有兩個參數的方法,並省略null打電話時:

    public String getFoo(Int32 a) 
    { 
        return getBar(a, "b", null); 
    } 
    
    public String getBar(Int32 a, String b) 
    { 
        //do something else, without the int 
    } 
    

    雖然你可能不希望這樣做,因爲你說你希望避免代碼重複。

  • 使用default代替null

    return getBar(a, "b", default(int)); 
    

    順便提及,這是相同的傳遞值0

+0

他的重載仍然需要一個可爲空的類型,或者需要大量的代碼重複。 – FlySwat 2008-11-06 21:36:08

相關問題