Answers:
没有人感到惊讶的是,C#4.0可选参数的工作方式如下:
public void SomeMethod(int a, int b = 0)
{
//some code
}
编辑:我知道在提出问题时,C#4.0不存在。但是这个问题在“ C#可选参数”中仍然在Google中排名第一,所以我想-这个答案值得在这里。抱歉。
另一种选择是使用params关键字
public void DoSomething(params object[] theObjects)
{
foreach(object o in theObjects)
{
// Something with the Objects…
}
}
叫做...
DoSomething(this, that, theOther);
public void log (params object[] args){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < args.Length; i++){ sb.Append("{"); sb.Append(i.ToString()); sb.Append("}"); sb.Append(" "); } String.Format(sb.ToString(),args).Dump(); }
示例调用:log("...Done,",(watch.ElapsedMilliseconds/1000).ToString(),"s");
在C#中,我通常会使用多种形式的方法:
void GetFooBar(int a) { int defaultBValue; GetFooBar(a, defaultBValue); }
void GetFooBar(int a, int b)
{
// whatever here
}
更新: 以上是我使用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#确实允许使用[Optional]属性(来自VB,尽管在C#中不起作用)。因此,您可以使用以下方法:
using System.Runtime.InteropServices;
public void Foo(int a, int b, [Optional] int c)
{
...
}
在我们的API包装器中,我们检测可选参数(ParameterInfo p.IsOptional)并设置默认值。目的是将参数标记为可选,而不必像在参数名称中使用“可选”那样费力。
如果希望运行时提供默认参数值,则必须使用反射进行调用。与这个问题的其他建议不一样,但与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("-");
}
字符串已经是可为null的类型,因此它们不需要??。
使用此方法后,以下调用均有效:
PrintValues (1, 2, 2.2f);
PrintValues (1, c: 1.2f);
PrintValues(b:100);
PrintValues (c: 1.2f, s: "hello");
PrintValues();
以这种方式定义方法时,您可以通过命名来自由设置所需的参数。有关命名和可选参数的更多信息,请参见以下链接:
可选参数用于方法。如果您需要一个类的可选参数,并且您是:
使用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#版本:您应该使用构造函数链接(使用:this关键字),其中较简单的构造函数会导致“主构造函数”。例:
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#4.0或更高版本
private void GetVal(string sName, int sRoll)
{
if (sRoll > 0)
{
// do some work
}
}
private void GetVal(string sName)
{
GetVal("testing", 0);
}
对于大量可选参数,可以将ContainsKey方法与Dictionary的单个参数一起使用。我喜欢这种方法,因为它允许我单独传递List或T,而不必创建其他方法(例如,将参数用作过滤器,则很好)。
示例(如果不需要可选参数,则将传递新的Dictionary <string,Object>()):
public bool Method(string ParamA, Dictionary<string,Object> AddlParams) {
if(ParamA == "Alpha" && (AddlParams.ContainsKey("foo") || AddlParams.ContainsKey("bar"))) {
return true;
} else {
return false;
}
}
晚会晚了一点,但我一直在寻找这个问题的答案,并最终想出了另一种方法。将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主页仍然显示参数列表(尽管您确实丢失了方便的文本输入框进行测试)。
我有一个编写有7个参数的Web服务。每个都是此Web服务包装的sql语句的可选查询属性。因此,我想到了两种针对非可选参数的解决方法...两者都非常差:
method1(参数1,param2,param 3,param 4,param 5,param6,param7)method1(param1,param2,param3,param 4,param5,param 6)方法1(param1,param2,param3,param4,param5,param7 )...开始查看图片。这种方式在于疯狂。方式太多组合。
现在以一种看起来比较尴尬但应该可以工作的简单方式:method1(param1,bool useParam1,param2,bool useParam2等)
那是一个方法调用,所有参数的值都是必需的,它将处理其中的每种情况。还很清楚如何从界面使用它。
这是一个hack,但可以使用。
万一有人要传递回调(或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;
}
如果默认值不可用,则添加可选参数的方法是使用.NET OptionalAttribute类-https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.interopservices.optionalattribute ?view = netframework-4.8
代码示例如下:
namespace OptionalParameterWithOptionalAttribute
{
class Program
{
static void Main(string[] args)
{
//Calling the helper method Hello only with required parameters
Hello("Vardenis", "Pavardenis");
//Calling the helper method Hello with required and optional parameters
Hello("Vardenis", "Pavardenis", "Palanga");
}
public static void Hello(string firstName, string secondName,
[System.Runtime.InteropServices.OptionalAttribute] string fromCity)
{
string result = firstName + " " + secondName;
if (fromCity != null)
{
result += " from " + fromCity;
}
Console.WriteLine("Hello " + result);
}
}
}
您也可以尝试此
类型1
public void YourMethod(int a=0, int b = 0)
{
//some code
}
2型
public void YourMethod(int? a, int? b)
{
//some code
}