是否可以在C#中使用条件参数?

时间:2013-10-29 16:10:50

标签: c# conditional optional-parameters

修改
如果您到这里寻找快速答案:可以这样做,但功能概述不会显示我正在寻找的结果。

如果省略其中一个可选但必需(因为...)参数,则答案'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;
}

是否有一种简单的方法可以强制执行此操作,或者我是否必须通知所有将要使用此功能的人员?

7 个答案:

答案 0 :(得分:3)

您可以在C sharp

中创建具有单独重载的方法签名
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 sharp中你可以使用可选参数。

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)

答案 1 :(得分:2)

因为方法参数共享类型重载单个方法会遇到麻烦。对于那些唯一允许的呼叫,您需要为每个呼叫分别使用。

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 :(得分:1)

您可以重新设计您的方法以接收您定义的包含所有这些信息的类的对象,或者您可以使用不同的参数创建多个方法,基本上是重载它或不同的方法。

我不认为你可以根据另一个参数的值来设置条件参数,就像这个参数是否存在一样,那么就不需要另一个,等等......

答案 3 :(得分:1)

将方法的重载链接在一起就是你的答案。这将允许每个人按照自己喜欢的方式管理它。

我已经在下面的例子中返回了链的字符串,但你可以很容易地在每个方法中添加逻辑,这样你最后就不会有一个令人讨厌的if语句。

    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;
    }

答案 4 :(得分:1)

尝试这种方法:

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)
{
   ...

答案 5 :(得分: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();

显然,完整的东西会包含问题中所有必需值的字段以及所有字段的流畅方法。

答案 6 :(得分: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了解详情。

请记住,即使在重载功能中也可以使用代码约定。

相关问题