2013-10-29 106 views
0

編輯:
如果你在這裏尋找快速的答案:這是可能的,但功能的概述並不顯示我正在尋找的結果。是否有可能在C#中有條件參數?

答案'Code Contracts' by Aidin給出了一個錯誤,如果你省略了一個可選的,但是必需的(因爲...)參數。這似乎是迫使用戶使用它的最簡單方式,但需要對該函數的用戶進行一些解釋。

答案'Place Logic in Class' by Shawn Holzworth符合我的需求,很容易地向用戶顯示功能的選項,但它需要不同的方法和大量的代碼重寫。


我試圖創建一個接受不同參數集的函數。在代碼中,我檢查給定的參數集合,並根據我對URL進行的操作來獲得一組包含來自保險公司的個人信息的值(這就是爲什麼沒有其他代碼)。 Google上的搜索沒有給出任何關於使參數彼此有條件的結果,因此我不確定這甚至是可能的。
基本的想法是有一個函數調用是這樣的:

dobFormatted 
, infodateFormatted 
, (BSN | insuranceID | lastname | postalcode, Homenummer[, Homenummeradd]) 
[, insuranceType] 

允許在這些方式中使用的功能:

  • dobFormatted, infodateFormatted, BSN
  • dobFormatted, infodateFormatted, BSN, insuranceType
  • dobFormatted, infodateFormatted, insuranceID
  • dobFormatted, infodateFormatted, insuranceID, insuranceType
  • dobFormatted, infodateFormatted, lastname
  • dobFormatted, infodateFormatted, lastname, insuranceType
  • dobFormatted, infodateFormatted, postalcode, Homenummer
  • dobFormatted, infodateFormatted, postalcode, Homenummer, insuranceType
  • dobFormatted, infodateFormatted, postalcode, Homenummer, Homenummeradd
  • dobFormatted, infodateFormatted, postalcode, Homenummer, Homenummeradd, insuranceType

因此,代碼會強制調用該函數包含所需的信息。我知道這可以通過創建需要不同參數集的函數的多個版本並返回當前函數的輸出來實現。不過,我認爲這會使代碼更少可讀性和可維護性。此外,還有3種方法僅使用3個字符串完成該功能,但輸出取決於第3個參數。


目前我有這樣的代碼:

public static string getVecozoURL(string dobFormatted, string infodateFormatted, 
     string BSN = "", string insuranceID= "", string lastname= "", 
     string postalcode = "", int Homenummer = 0, string Homenummeradd = "", 
     string insuranceType = "Both") { 
    string URL= ""; 
    if (FCelfproef.BSN(BSN)) { 
     // Do stuff 
    } else if (!insuranceID.IsEmpty()) { 
     // Do stuff 
    } else if (postalcode .Length > 4 && Homenummer > 0) { 
     // Do stuff 
    } else if (!lastname.IsEmpty()) { 
     // Do stuff 
    } 
    // Do some other stuff 
    return URL; 
} 

有沒有一種簡單的方法來迫使這還是我來通知要使用此有關的功能的方式,所有的人作品?

+10

單獨重載。 – SLaks

+0

@SLaks大部分參數都是字符串,有些是聯合值。在這種情況下,重載不起作用。 –

回答

1

只要您打開過載功能,所有這些解決方案都很棒。我會親自重載這個函數;然而,如果你堅持只使用一個函數,那麼我強烈建議你使用代碼合約來強制執行任何你想要的任何邏輯來組合參數。這裏是一個例子:

public string XYZ(string dobFormatted, string infodateFormatted, 
     string BSN = "", string insuranceID= "", string lastname= "", 
     string postalcode = "", int Homenummer = 0, string Homenummeradd = "", 
     string insuranceType = "Both") 
{ 
    Contract.Requires(!string.IsNullOrEmpty(dobFormatted) || insuranceType == "NONE");  
} 

你可以有任意多的Requires()函數。您可以啓用代碼合同的靜態檢查,編譯器可以在您危及約束時發出警告。

訪問http://msdn.microsoft.com/en-us/library/dd264808.aspx瞭解更多信息。

請記住,即使在您的重載函數中也可以使用Code Contracts。

+0

我必須更仔細地研究這一點,但從我可以找到的東西的外觀來看,它似乎符合我的需求。感謝迄今的信息。 –

+0

我認爲這是首選答案。因爲如果使用不符合要求,則會產生錯誤。然而,由於我與之合作的人,最好實施[Shawn Holzworth]的答案(http://stackoverflow.com/a/19664315/1249357)。 –

3

可以在C調

public void TestMethod(string stringValue, int intValue) 
public void TestMethod(double doubleValue, int intValue) 
public void TestMethod(string stringValue, string otherStringValue) 
public void TestMethod(string stringValue, int intValue, string otherStringValue) 

這些創建單獨的重載方法簽名均能被稱爲單獨的方法。

Overloads


此外,在C調,您可以使用可選的參數。

public void TestMethod(int intValue 
         ,int optionalIntValue = 0 
         ,int optionalSecondValue = 4) 

在那裏你可以調用像

TestMethod(1) 
//optionalValue = 0(default) & optionalSecondValue = 4(default) 

TestMethod(1, optionalSecondValue:2) 
//optionalValue = 0(default) & optionalSecondValue = 2 

TestMethod(1, 12) 
//optionalValue = 12 & optionalSecondValue = 4(default) 
+0

儘管這些選項都不起作用。 –

1

你可以重新設計你的方法採取在包含所有這些信息,或者您可以創建具有不同參數的多個方法,您定義的類的對象,基本上是重載它或不同的方法。

我不認爲你可以基於其他參數的值必須條件參數,如如果該參數是存在的,那麼就不需要其他的,還是等等...

1

串聯起來該方法的重載是你的答案。這將允許每個人管理他們的想法。

我已經在下面的例子中返回了鏈的字符串,但是您可以輕鬆地將邏輯添加到每個方法中,以便您在末尾沒有討厭的if語句。由於該方法的參數類型份額重載一個方法是要遇到麻煩

public enum VecozoOverloadedOptions { BSN, InsuranceID, LastName, PostalCode }; 

public class VecozoValues 
{ 
    public string DobFormatted; 
    public string infodateFormatted; 
    public VecozoOverloadedOptions OverloadChoice; 
    public string OverloadedValue; 
    public int Homenummer; 
    public string Homenummeradd; 
    public string InsuranceType; 
} 

... 

public static string getVecozoURL(VecozoValues data) 
{ 
    ... 
+0

一個很好的建議,但是有多個選項只有參數的名稱作爲差異,所以類型仍然是'string,string,string,optional string',其中的3個(在帖子的第2段中提到過) –

1

試試這個辦法。對於那些是唯一允許的呼叫,您需要爲每個呼叫分別使用不同的方法。

public static string getVecozoURL_BSN(string dobFormatted, string infodateFormatted, string BSN, string insuranceType = "Both") 
public static string getVecozoURL_InsurranceID(string dobFormatted, string infodateFormatted, string insuranceID, string insuranceType = "Both") 
public static string getVecozoURL_Lastname(string dobFormatted, string infodateFormatted, string lastname, string insuranceType = "Both") 
public static string getVecozoURL_Postalcode(string dobFormatted, string infodateFormatted, string postalcode, int Homenummer, string Homenummeradd = "", string insuranceType = "Both") 

但是,由於您關心的是可讀性/可維護性,將邏輯封裝在自己的類中可能更有意義。喜歡的東西:

class VecozoURLFormater 
{ 
    public string DobFormatted { get; private set; } 
    public string InfodateFormatted { get; private set; } 
    public string InsuranceType { get; private set; } 
    public VecozoURLFormater(string dobFormatted, string infodateFormatted, string insuranceType = "Both") 
    { 
     DobFormatted = dobFormatted; 
     InfodateFormatted = infodateFormatted; 
     InsuranceType = insuranceType; 
    } 

    public string FromBSN(string BSN){/*...*/} 
    public string FromInsurranceID(string insuranceID){/*...*/} 
    public string FromLastname(string lastname){/*...*/} 
    public string FromPostalcode(string postalcode, int Homenummer, string Homenummeradd = "") {/*...*/} 
} 
2

public static string getVecozoURL(string dobFormatted, string infodateFormatted, string BSN) 
    { 
     return getVecozoURL(dobFormatted, infodateFormatted, BSN, "", "", "", 0, "", "Both"); 
    } 

    public static string getVecozoURL(string dobFormatted, string infodateFormatted, string BSN, string insuranceID) 
    { 
     return getVecozoURL(dobFormatted, infodateFormatted, BSN, insuranceID, "", "", 0, "", "Both"); 
    } 

    public static string getVecozoURL(string dobFormatted, string infodateFormatted, string BSN, string postalcode, int Homenummer) 
    { 
     return getVecozoURL(dobFormatted, infodateFormatted, BSN, "", "", postalcode, Homenummer, "", "Both"); 
    } 

    public static string getVecozoURL(string dobFormatted, string infodateFormatted, 
    string BSN, string insuranceID, string lastname, 
    string postalcode, int Homenummer, string Homenummeradd, 
    string insuranceType) 
    { 
     string URL = ""; 
     if (FCelfproef.BSN(BSN)) 
     { 
      // Do stuff 
     } 
     else if (!insuranceID.IsEmpty()) 
     { 
      // Do stuff 
     } 
     else if (postalcode.Length > 4 && Homenummer > 0) 
     { 
      // Do stuff 
     } 
     else if (!lastname.IsEmpty()) 
     { 
      // Do stuff 
     } 
     // Do some other stuff 
     return URL; 
    } 
+0

我目前正在尋找[Aidin](http://stackoverflow.com/a/19666045/1249357)的答案,如果這不符合我的需要,我會採用此解決方法。 –

+0

儘管這可能不是最好的答案,但對於我和我一起工作的人來說,這是最好的答案。謝謝你的回答。 –

1

這種類型的問題往往是最好用流利的語法解決:

public class VecozoURLBuilder 
{ 
    private string _dobFormatted; 
    private string _infodateFormatted; 
    private string _bsn; 
    private string _insuranceID; 
    ... 

    public VecozoURLBuilder DobFormatted(string dobFormatted) 
    { 
     _dobFormatted = dobFormatted; 
     return this; 
    } 

    public VecozoURLBuilder InfodateFormatted(string infodateFormatted) 
    { 
     _infodateFormatted= nfodateFormatted; 
     return this; 
    } 
    ... 

    public string VecozoURL() 
    { 
     // create string from dobFormatted etc. 
    } 
} 

它是那麼像這樣使用:

var url = new VecozoURLBuilder() 
    .DobFormatted("xxx") 
    .InfodateFormatted("yyy") 
    .VecozoURL(); 

顯然,全事情會所有字段都有問題所需的所有值和所有字段的流暢方法的字段。

+1

我還會從每個流利的調用中返回接口而不是* VecozoURLBuilder * - 這樣您將指導用戶如何使用API​​。 – galenus

+0

當我必須創建其他人/公司想要/必須使用的API時,我會記住這一點。在這種情況下,每個必須使用它的人都必須完成一個簡單的課程來獲取證書,以便如何使用我在此函數中封裝的鏈接(法律)。因此我認爲沒有必要像這樣創建一個API。 –

相關問題