注意:这个问题是在同一时间问时C#还不支持可选参数(即前C#4)。
我们正在创建一个真实编程方式从C#类生成一个Web API。 类有方法GetFooBar(int a, int b)
和API有一个方法GetFooBar
服用查询参数等&a=foo &b=bar
。
这些类需要支持可选参数,这是不是在C#所支持的语言。 什么是最好的方法呢?
注意:这个问题是在同一时间问时C#还不支持可选参数(即前C#4)。
我们正在创建一个真实编程方式从C#类生成一个Web API。 类有方法GetFooBar(int a, int b)
和API有一个方法GetFooBar
服用查询参数等&a=foo &b=bar
。
这些类需要支持可选参数,这是不是在C#所支持的语言。 什么是最好的方法呢?
惊讶没有人提到C#4.0是这样工作的可选参数:
public void SomeMethod(int a, int b = 0)
{
//some code
}
编辑:我知道,在这个问题被问的时候,C#4.0中是不存在的。 但这个问题仍然位居第一的谷歌“C#可选参数”所以我想 - 这个答案值得在这儿。 抱歉。
另一种选择是使用params关键字
public void DoSomething(params object[] theObjects)
{
foreach(object o in theObjects)
{
// Something with the Objects…
}
}
所谓的喜欢...
DoSomething(this, that, theOther);
在C#中,我通常使用的方法的多种形式:
void GetFooBar(int a) { int defaultBValue; GetFooBar(a, defaultBValue); }
void GetFooBar(int a, int b)
{
// whatever here
}
UPDATE:这上面提到的是,我没有默认值与C#2.0的方式。 现在我工作的项目使用的是C#4.0现在直接支持可选参数。 这里是我只是在我自己的代码中使用的例子:
public EDIDocument ApplyEDIEnvelop(EDIVanInfo sender,
EDIVanInfo receiver,
EDIDocumentInfo info,
EDIDocumentType type
= new EDIDocumentType(EDIDocTypes.X12_814),
bool Production = false)
{
// My code is here
}
从这个站点:
http://www.tek-tips.com/viewthread.cfm?qid=1500861&page=1
C#确实允许使用[可选]属性(从VB,虽然在C#不是功能性的)。 所以,你可以有这样的方法:
using System.Runtime.InteropServices;
public void Foo(int a, int b, [Optional] int c)
{
...
}
在我们的API的包装,我们发现可选参数(的ParameterInfo p.IsOptional)并设置默认值。 我们的目标是,以纪念参数可选,而不诉诸于组装机一样的参数名称为“可选”。
你可以使用方法重载...
GetFooBar() GetFooBar(int a) GetFooBar(int a, int b)
这取决于方法签名,我给的例子是缺少“INT B”唯一的方法,因为它会具有相同的签名为“诠释了”方法。
你可以使用可空类型...
GetFooBar(int? a, int? b)
然后,您可以检查,使用a.HasValue,看看是否有一个参数被设置。
另一种选择是使用“PARAMS”参数。
GetFooBar(params object[] args)
如果你想一起去命名参数也需要创建一个类来处理它们,但我认为已经有这样的网络应用程序的。
您可以在C#4.0中使用可选参数无任何后顾之忧。 如果我们有一个方法,如:
int MyMetod(int param1, int param2, int param3=10, int param4=20){....}
当你调用该方法,可以跳过这样的参数:
int variab = MyMethod(param3:50; param1:10);
C#4.0实现了一个叫“命名参数”功能,您可以通过它们的名字实际上传递参数,当然你可以传递参数,任何你想要的顺序:)
如果你想运行时提供一个默认的参数值,你必须使用反射来拨打电话。 没有像你一样对这个问题的其他建议,但用VB.NET兼容。
using System;
using System.Runtime.InteropServices;
using System.Reflection;
namespace ConsoleApplication1
{
class Class1
{
public static void sayHelloTo(
[Optional,
DefaultParameterValue("world")] string whom)
{
Console.WriteLine("Hello " + whom);
}
[STAThread]
static void Main(string[] args)
{
MethodInfo mi = typeof(Class1).GetMethod("sayHelloTo");
mi.Invoke(null, new Object[] { Missing.Value });
}
}
}
一个简单的方法,让您在任何位置遗漏任何参数 ,是趁着空类型如下:
public void PrintValues(int? a = null, int? b = null, float? c = null, string s = "")
{
if(a.HasValue)
Console.Write(a);
else
Console.Write("-");
if(b.HasValue)
Console.Write(b);
else
Console.Write("-");
if(c.HasValue)
Console.Write(c);
else
Console.Write("-");
if(string.IsNullOrEmpty(s)) // Different check for strings
Console.Write(s);
else
Console.Write("-");
}
字符串已经空类型,使他们不需要? 。
一旦你有了这个方法,下面的调用都是有效的 :
PrintValues (1, 2, 2.2f);
PrintValues (1, c: 1.2f);
PrintValues(b:100);
PrintValues (c: 1.2f, s: "hello");
PrintValues();
当你定义一个方法,这样你可以自由通过命名并设置你想要的参数。 请参阅以下链接,命名和可选参数的详细信息:
命名和可选参数(C#编程指南)@ MSDN
我同意stephenbayer。 但由于它是一个Web服务,它是更容易为最终用户使用的一种形式将WebMethod,比使用相同的方法的多个版本。 我认为,在这种情况下,可空类型是完美的可选参数。
public void Foo(int a, int b, int? c)
{
if(c.HasValue)
{
// do something with a,b and c
}
else
{
// do something with a and b only
}
}
可选参数是方法。 如果你需要一类可选参数,你是:
使用C#4.0:在课堂上,一个解决方案,我更喜欢的构造函数中使用可选的参数,因为它更接近的是与方法完成的,因此更容易记住。 这里有一个例子:
class myClass { public myClass(int myInt = 1, string myString = "wow, this is cool: i can have a default string") { // do something here if needed } }
使用之前的C#4.0 C#版本:你应该使用构造函数链(使用:这个关键字),其中简单的构造导致“主构造函数”。 例:
class myClass { public myClass() { // this is the default constructor } public myClass(int myInt) : this(myInt, "whatever") { // do something here if needed } public myClass(string myString) : this(0, myString) { // do something here if needed } public myClass(int myInt, string myString) { // do something here if needed - this is the master constructor } }
这是在C#作为斯蒂芬提到处理的典型方法是重载方法。 通过创建具有不同参数的方法的多个版本,您可以有效地创建可选参数。 在用较少的参数表格,你通常会调用所有的参数调用该方法设置默认值的方法的形式。
可以重载你的方法。 一种方法包含一个参数GetFooBar(int a)
而另一个含有这两个参数, GetFooBar(int a, int b)
取而代之的默认参数,为什么不从构建查询字符串一本字典类过去了..这是几乎相同的方式asp.net形式与查询字符串工作的实现。
即的Request.QueryString [ “一个”]
这将从工厂/样板代码分离的叶类。
您可能还需要检查网络服务与ASP.NET 。 Web服务是通过对C#类属性自动生成一个Web API。
有点迟到了,但我一直在寻找这个问题的答案,并最终想出了另一种方式来做到这一点。 声明你的Web方法的可选ARGS数据类型为XmlNode类型。 如果可选ARG被省略,这将被设置为null,如果它的存在,你可以得到的字符串值,通过调用arg.Value,即
[WebMethod]
public string Foo(string arg1, XmlNode optarg2)
{
string arg2 = "";
if (optarg2 != null)
{
arg2 = optarg2.Value;
}
... etc
}
什么是体面也对这种做法是.NET生成主页的WS仍然显示参数列表(虽然你失去了方便的文本输入框用于测试)。
我有一个Web服务编写需要7个参数。 每个是一个可选的查询属性通过此Web服务包的SQL语句。 因此,两种方法可以解决非可选PARAMS浮现在脑海中......都是很可怜:
方法1(参数1,参数2,参数3,PARAM 4,PARAM 5,PARAM 6,param7)方法1(参数1,参数2,参数3,PARAM 4,param5,PARAM 6)方法1(参数1,参数2,参数3,param4,param5,param7 )...开始看到的景象。 这样疯狂的谎言。 太多的组合。
现在看起来笨拙,但应该工作更简单的方法:方法1(参数1,布尔useParam1,参数2,布尔useParam2,等...)
这是一个方法调用,需要对所有参数的值,它会处理它里面每一种情况下。 它也清楚如何从接口使用它。
这是一个黑客,但它会奏效。
我不得不这样做在VB.Net 2.0的Web服务。 我结束了作为字符串指定的参数,然后将它们转换成我需要什么。 一个可选参数,用一个空字符串指定。 不干净的解决方案,但它的工作。 只是要小心,你捕捉到所有可能发生的异常。
为了以防万一,如果有人想通过回调(或delegate
)作为可选的参数,可以这样来做。
可选的回调参数:
public static bool IsOnlyOneElement(this IList lst, Action callbackOnTrue = (Action)((null)), Action callbackOnFalse = (Action)((null)))
{
var isOnlyOne = lst.Count == 1;
if (isOnlyOne && callbackOnTrue != null) callbackOnTrue();
if (!isOnlyOne && callbackOnFalse != null) callbackOnFalse();
return isOnlyOne;
}
可选参数是什么,但默认参数! 我建议你把他们都默认参数。 GetFooBar(INT A = 0,INT B = 0),如果你没有任何过载的方法,将导致= 0,B = 0,如果你不传递任何值,如果传递1个值,将导致,通过对于一个数值,0和如果传递2个值第一将被分配到一个和第二到b。
希望这能回答你的问题。
你可以试试这个太
1型
public void YourMethod(int a=0, int b = 0) { //some code }
2型
public void YourMethod(int? a, int? b) { //some code }