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吗?