简体   繁体   English

C#中可以有条件参数吗?

[英]Is it possible to have conditional parameters in C#?

EDIT: 编辑:
If you got here looking for the fast answer: It is possible to do this, but the overview of the function does not show the result I was looking for. 如果您在这里寻找快速答案:可以这样做,但是该功能的概述并未显示我所寻找的结果。

The answer 'Code Contracts' by Aidin gives an error if you omit one of the optional, but required (because...) parameters. 如果省略可选参数(但由于(因为...)是必需的)之一,则Aidin的“代码合同”答案将导致错误。 This seems to be the easiest way to force it upon your user, but requires some explanation to the user of the function. 这似乎是将其强加给您的用户的最简单方法,但是需要对该功能的用户进行一些解释。

The answer 'Place Logic in Class' by Shawn Holzworth fitted my need of easily showing the user of the function what options they have, but it requires a different approach and a lot of code rewriting. Shawn Holzworth的答案“在类中放置逻辑”满足了我的需求,即可以轻松地向函数用户显示其具有哪些选项,但是它需要使用不同的方法和大量的代码重写。


I'm trying to create a function that accepts different sets of parameters. 我正在尝试创建一个接受不同参数集的函数。 In the code I check what set of parameters are given and based on that I do something to the URL in order to receive a set of values containing personal information from insurance companies (that is why there is no other code). 在代码中,我检查给出了哪些参数集,并根据该参数对URL进行了处理,以便从保险公司接收包含个人信息的一组值(这就是为什么没有其他代码)的原因。 A search on Google gave no results on making the parameters conditional on each other, therefore I'm not sure it is even possible. 在Google上进行的搜索未给出使参数彼此为条件的结果,因此,我不确定是否有可能。
Basically the idea is to have a function call like this: 基本上,想法是像这样进行函数调用:

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

Allowing the function to be used in these ways: 允许以以下方式使用该功能:

  • 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

So the code forces the call to the function to contain the required information. 因此,代码强制对函数的调用包含所需的信息。 I'm aware that this could be achieved by creating multiple versions of the function requiring different sets of parameters and returning the output of the current function. 我知道可以通过创建需要不同参数集的函数的多个版本并返回当前函数的输出来实现。 However I think that would make the code less readable and maintainable. 但是,我认为这会使代码的可读性和可维护性降低。 Besides, there are also 3 ways of completing the function using only 3 strings, but the output depends on the 3rd parameter. 此外,还有3种方法可以仅使用3个字符串来完成功能,但是输出取决于第3个参数。


Currently I have this code: 目前,我有以下代码:

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

Is there a easy way to force this or do I have to inform all people that are going to use this about the way the function works? 是否有一种简单的方法可以强制执行此操作,或者我是否必须告知所有将要使用此功能的人员该功能的工作方式?

You can create method signatures with separate overloads in C sharp 您可以在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)

These could all be called as separate methods. 这些都可以称为独立方法。

Overloads 超载


Also in C sharp you can use optional parameters. 同样在C Sharp中,您可以使用可选参数。

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

where you could call like 你可以打电话给

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)

Because the method parameters share types overloading a single method is going to run into trouble. 由于方法参数共享类型的重载,因此单个方法会遇到麻烦。 For those to be the only allowable calls you'll need separate methods for each. 为了使这些成为唯一允许的调用,您需要为每个调用单独的方法。

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")

However since you're concerned with readability/maintainability, it may make more sense to encapsulate the logic in it's own class. 但是,由于您关注的是可读性/可维护性,因此将逻辑封装在其自己的类中可能更有意义。 Something like: 就像是:

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 = "") {/*...*/}
}

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... 我不认为您可以基于另一个参数的值来使用条件参数,就像该参数在那里一样,则不需要另一个,依此类推...

Chaining together overloads of the method is your answer. 将方法的重载链接在一起是您的答案。 This will allow everyone to manage it how they'd like. 这将使每个人都能按自己的意愿进行管理。

I have returned the string of the chain in the example below, but you could easily add logic into each method so that you didnt have a nasty if statement at the end. 我在下面的示例中返回了链的字符串,但是您可以轻松地向每个方法中添加逻辑,以便最后没有讨厌的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;
    }

Try this approach: 试试这个方法:

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

This type of problem is often best solved with a fluent syntax: 通常,使用流利的语法可以最好地解决此类问题:

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

It is then used like this: 然后按以下方式使用:

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

Obviously, the full thing would have fields for all the required values in the question and fluent methods for all the fields. 显然,完整的问题将具有问题中所有必需值的字段以及所有字段的流利方法。

All of these solutions are great as long as you are open to overload your functions. 只要您愿意过载功能,所有这些解决方案都是不错的选择。 I would personally overload the function; 我个人会重载该功能; however, if you persist to use only one function then I highly recommend you to use Code Contracts to enforce any logic you desire to any combinations of parameters. 但是,如果您坚持只使用一个功能,那么我强烈建议您使用代码协定对参数的任何组合强制执行所需的任何逻辑。 Here is an example: 这是一个例子:

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

You can have as many as Requires() functions as you want. 您可以根据需要拥有多达Requires()函数。 You can enable the static check for Code Contracts and compiler can warn you when you are jeopardizing your constrains. 您可以为代码协定启用静态检查,并且在危及约束时编译器会警告您。

Visit http://msdn.microsoft.com/en-us/library/dd264808.aspx for more information. 有关更多信息,请访问http://msdn.microsoft.com/en-us/library/dd264808.aspx

Remember you can use Code Contracts even in your overloaded functions. 请记住,即使在重载的函数中也可以使用代码协定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM