C# 灵活的方法参数?

C# 灵活的方法参数?,c#,sql,C#,Sql,我有一个使用以下方法的类 public cIPLink(int paramCaseNo, int paramIPID, string paramIPReference, int paramContactID) { this.cLinkDate = DateTime.Now; this.cCaseNo = paramCaseNo; this.cIPID = paramIPID; this.cIPRefe

我有一个使用以下方法的类

public cIPLink(int paramCaseNo, int paramIPID, string paramIPReference, int paramContactID)
    {            
        this.cLinkDate = DateTime.Now;
        this.cCaseNo = paramCaseNo;
        this.cIPID = paramIPID;
        this.cIPReference = paramIPReference;
        this.cContactID = paramContactID;

        string strConnect = BuildConnectionString();
        SqlConnection linkToDB = new SqlConnection(strConnect);
        linkToDB.Open();

        string sqlStat = "INSERT INTO tblIPLinks (LinkID, LinkDate, CaseNo, IPID, ContactID, IPReference)" +
                         "VALUES (@LinkID, @LinkDate, @CaseNo, @IPID, @ContactID, @IPReference);";
        SqlCommand sqlCom = new SqlCommand(sqlStat, linkToDB);

        sqlCom.Parameters.Add("@LinkID", SqlDbType.Int);
        sqlCom.Parameters.Add("@LinkDate", SqlDbType.Date);
        sqlCom.Parameters.Add("@CaseNo", SqlDbType.Int);
        sqlCom.Parameters.Add("@IPID", SqlDbType.Int);
        sqlCom.Parameters.Add("@ContactID", SqlDbType.Int);
        sqlCom.Parameters.Add("@IPReference", SqlDbType.Text);

        this.cLinkID = NextLinkID();

        sqlCom.Parameters["@LinkID"].Value = this.cLinkID;
        sqlCom.Parameters["@LinkDate"].Value = this.cLinkDate;
        sqlCom.Parameters["@CaseNo"].Value = this.cCaseNo;
        sqlCom.Parameters["@IPID"].Value = this.cIPID;
        sqlCom.Parameters["@ContactID"].Value = this.cContactID;
        sqlCom.Parameters["@IPReference"].Value = this.cIPReference;

        sqlCom.ExecuteNonQuery();

        linkToDB.Close();
    }
不过我想让它更灵活一点。有时调用该方法时,我想删除字段IPID,有时我想删除字段ContactID。现在我考虑复制和粘贴这段代码,并使用三种重载方法;一个只有IPID,一个只有ContactID,第三个两个字段,但我相信一定有一种更整洁的方式来做我想做的事情


有什么想法吗?

如果您使用的是dotnet 4.0及以上版本,您可以使用可选参数

public cIPLink(int paramCaseNo, int paramIPID = -1, 
    string paramIPReference = null, int paramContactID = -1)
因此,从那一刻起,您可以如下调用它:

cIPLink( paramCaseNo );
cIPLink( paramCaseNo, paramContactID:5 );
在C#4.0中,可以使用命名参数和可选参数。如果你有这样的方法:

static int CalculateBMI(int weight, int height)
{
    return (weight * 703) / (height * height);
}
你可以这样称呼它:

    Console.WriteLine(CalculateBMI(123, 64));
或类似于以下任何一种:

    Console.WriteLine(CalculateBMI(weight: 123, height: 64));
    Console.WriteLine(CalculateBMI(height: 64, weight: 123));

    Console.WriteLine(CalculateBMI(123, height: 64));
在声明上设置初始值使其成为可选的:

public int area(int height = 0, int width = 0)
{
    return height * width;
}

如果使用C#4.0,则使用可选参数使此方法采用可为null的
int?
而不是普通的
int
,更改代码以注意其中的
null
值,并添加三个单行重载,将调用转发到do work private方法

private void cIPLinkImpl(int paramCaseNo, int? paramIPID, string paramIPReference, int? paramContactID) {
    // Your implementation goes here.
    // check paramIPID and paramContactID to null before using them here
}

public void cIPLink(int paramCaseNo, int paramIPID, string paramIPReference, int paramContactID) {
    cIPLinkImpl(paramCaseNo, paramIPID, paramIPReference, paramContactID);
}

public void cIPLink(int paramCaseNo, string paramIPReference, int paramContactID) {
    cIPLinkImpl(paramCaseNo, null, paramIPReference, paramContactID);
}

public void cIPLink(int paramCaseNo, int paramIPID, string paramIPReference) {
    cIPLinkImpl(paramCaseNo, paramIPID, paramIPReference, null);
}

您可以使用默认参数,如

public cIPLink(int paramCaseNo, string paramIPReference, int paramIPID = -1, int paramContactID = -1)

其中一个想法是将这些参数移动到类中,类似于:

public class QueryParameters 
{
     public int? CaseNo {get;set;} 
     public int? IPID {get;set;} 
     public string IPReference {get;set;}
     public int? ContactID {get;set;}
}
然后,不再将许多参数作为参数传递,而是传递QueryParameters类型的单个参数,并在传递到方法时填充QueryParameters的必需属性:

QueryParameters queryParameters = new QueryParameters();
queryParameters.IPReference = "blabla";

...

public cIPLink(QueryParameters queryParameters) 
{
    if (queryParameters.CaseNo.HasValue) {
        ....
    }
    ...
}

总的来说,建议不要超过4-5个方法参数,最好将它们重构为单独的类。

您只需将参数的默认值设置为null,然后在逻辑中检查并设置它们:

void method(int value = -1, string something = null) {
  if (value != -1) ... add parameter
  if (something != null) ... add parameter
}

我认为大多数情况下可选参数都是邪恶的——google“optional argumens c#evil”(引用:在c#4中引入可选参数的原因首先是为了支持COM互操作。)我想知道这是否是推荐的方法,即使我有大约30-40个这样的方法(有4-8个参数)。我应该为每个方法创建一个“parameters”类吗?如果您的大多数方法都有4-8个参数,那么您在单个方法中做的太多了,我认为(对于每个测试,您也需要4-8个参数),这可能是您违反了单一责任原则。如果它是一个大型的解决方案,并且只有几个方法具有这样的参数计数,那么最好将这些参数分组到类中,这样不仅可以生成更易于维护的代码,而且更易于阅读-您不需要长时间的方法调用,因为您可以在单独的行中创建对象。无论如何,没有严格的规则,您需要为每个具体情况自行决定。这些参数将提交到HTTP请求中。因此,它不会破坏SRP,因为HTTP请求可以向服务器发送不同的数据,其中一些是可选的。例如,设想一个“获取用户”HTTP API调用,在这里我可以指定用户的名字、电子邮件和(可选地)某种类型的日期范围等。您会考虑这种API来中断SRP吗?