0

编辑:
如果您到这里寻找快速答案:可以这样做,但该功能的概述并未显示我正在寻找的结果。

如果您省略了可选但必需的(因为...)参数之一,Aidin的答案“代码合同”会给出错误。这似乎是强制用户使用它的最简单方法,但需要对函数的用户进行一些解释。

Shawn Holzworth的答案“Place Logic in Class”符合我轻松向函数用户展示他们有哪些选项的需求,但它需要不同的方法和大量的代码重写。


我正在尝试创建一个接受不同参数集的函数。在代码中,我检查给出了哪些参数集,并基于此对 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 个字符串完成功能,但输出取决于第三个参数。


目前我有这个代码:

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

是否有一种简单的方法来强制执行此操作,或者我是否必须告知所有将要使用此功能的人该功能的工作方式?

4

7 回答 7

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)

这些都可以称为单独的方法。

重载


同样在 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)
于 2013-10-29T16:21:37.490 回答
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 = "") {/*...*/}
}
于 2013-10-29T16:46:19.890 回答
1

You can redesign your method to take in an object of a class that you define containing all this info, or you can create multiple methods with different parameters, basically either overload it or different methods.

I do not think that you could have conditional parameters based on the value of another parameter, as in if this parameter is there, then don't need the other, or so on...

于 2013-10-29T16:22:24.277 回答
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了解更多信息。

请记住,即使在重载函数中也可以使用代码协定。

于 2013-10-29T18:13:43.323 回答
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;
    }
于 2013-10-29T16:26:05.923 回答
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();

显然,完整的内容将包含问题中所有必需值的字段和所有字段的流利方法。

于 2013-10-29T17:01:22.003 回答
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)
{
   ...
于 2013-10-29T16:45:58.880 回答