2014-02-12 31 views
2

我有一個函數可能不會傳遞任何東西,或者將一個null傳遞給F(params String [] values)?

public List<Item> Filter(params String[] valuesOrdered) 
{ 
    //... 
} 

其充當關於所有Item秒的過濾器。

public class Item 
{ 
    List<String> propertiesOrdered; 
    //... 
} 

因此,如果我打電話給Filter("prop1"),然後全部Item s與"prop1"作爲他們的屬性將被匹配的第一個條目。

如果我打電話Filter(),則應返回所有Item

我還需要能夠匹配null值。因此,現在我可以撥打Filter(null, null)和所有Itemnull, null作爲他們的第一個屬性將匹配。

所有這些工作,除非我打電話Filter(null)。它的解釋方式與Filter()相同,但意圖是前者應返回所有Item s,null作爲其第一個屬性,後者應歸還所有Item s。

我試圖定義過載處理這個

public List<Item> Filter(String value) 
{ 
    if(value == null) 
     return Filter(new String[] {null}); 
    else 
     return Filter(value); 
} 

但是,編譯器只顯示一個Ambiguous Invocation錯誤,當我打電話Filter(null)

+1

請注意,即使您的超載原來沒有幫助,它應該讀取'公開列表 Filter(String value){return Filter(new [] {value}); }'。這很簡單,並始終調用原始超載(以正確的方式),而在'value'非空的情況下,您自己調用了遞歸式無限期。 (請注意'Filter(value)'不是不明確的。) –

+0

@JeppeStigNielsen啊是的。好東西,它不是因爲其他呼叫而在第一個地方建立的:) –

回答

2

如果你放棄過載,那麼這樣的:

Filter(null); 

將被稱爲本:

string[] valuesOrdered = null; 
Filter(valuesOrdered); 

,而不是像這樣:

Filter(new string[] { null }); 

所以,你可以檢測到這一點,如果你希望它的行爲就像你傳遞一個數組containsin GA單null,那麼這個就足夠了:

public List<Item> Filter(params String[] valuesOrdered) 
{ 
    valuesOrdered = valuesOrdered ?? new string[] { null }; 

    //... 
} 

需要注意的是這樣的:

Filter(); 

實際上將被稱爲本:

Filter(new string[0]); 

所以兩者之間的區別你可以檢測到。

下面是一個簡單LINQPad程序演示:

void Main() 
{ 
    Filter(); 
    Filter(new[] { "a" }); 
    Filter("a"); 
    Filter(null); 
} 

public static void Filter(params string[] values) 
{ 
    values.Dump(); 
} 

輸出:

LINQPad output

1

您可以使用語法

Filter((String)null) 

調用該方法在其「擴大「形式與長度一個數組。

如果語法是不愉快的話,你可能要定義一個常量

const String NullStr = null; 

,並使用

Filter(NullStr) 

代替。

PS!我個人更喜歡string而不是String,但我堅持你的約定,因爲它與你的問題無關。

+0

確實如此,但調用者不一定知道這個細節,所以我不認爲這是一個'乾淨'的解決方案。 –

+0

關於你的編輯:仍然用'NullStr'定義,調用者可能不知道它,太容易傳遞null。在這種情況下,我更喜歡Lasse的回答。 關於PS:謝謝,是的,我只是希望保持關鍵字和類型(包括別名)使用一致的語法分隔。 –

+0

@DavidS。那麼,來電者應該知道這一點。正如他應該知道'string.Concat(null);'與'string.Concat((string)null);'和'Activator.CreateInstance(typeof(Uri),null);'不同於' Activator.CreateInstance(typeof(Uri),(string)null);'等等。這對於C#語言是通用的,如果調用者選擇C#進行調用,他應該知道。在我看來,讓一個'null'數組代表一個長度爲1的數組,它的唯一入口爲空,就像Karlsen在他的回答中所做的那樣。但我猜,這是一個口味問題。 –

相關問題