它们听起来都很相似。来自msdn:
ParameterInfo.IsOptional
获取一个值,该值指示此参数是否为可选参数。 此方法依赖于可选元数据标志。编译器可以插入此标志,但编译器不必这样做。 此方法利用ParameterAttributes枚举数的可选标志。
ParameterInfo.HasDefaultValue (在.NET 4.5中新增)
获取一个值,该值指示此参数是否具有默认值。
它们不是一样的吗?我做了快速测试:
public void A(string value)
{
}
public void B(string value, int i = -1)
{
}我写道:
var a = AInfo.GetParameters().Select(p => p.HasDefaultValue).ToArray();
var b = AInfo.GetParameters().Select(p => p.IsOptional).ToArray();
var c = BInfo.GetParameters().Select(p => p.HasDefaultValue).ToArray();
var d = BInfo.GetParameters().Select(p => p.IsOptional).ToArray();
//a equals b; and c equals d那么,它们在什么情况下是不同的呢?为什么BCL在新的HasDefaultValue 4.5中引入.NET?
发布于 2013-04-24 09:03:20
如果我们查看IsOptional的实现,我们将看到:
public bool IsOptional
{
[__DynamicallyInvokable] get
{
return (this.Attributes & ParameterAttributes.Optional) != ParameterAttributes.None;
}
}它依赖于元数据标志,但它是在msdn中编写的:
此方法依赖于可选元数据标志。编译器可以插入此标志,但编译器不必这样做。
这意味着它取决于编译器,如果我们使用其他编译器,则可以获得具有默认值的参数将不具有IsOptional标志。现在让我们看看HasDefaultValue属性是如何实现的:
public override bool HasDefaultValue
{
get
{
if (this.m_noMetadata || this.m_noDefaultValue)
return false;
else
return this.GetDefaultValueInternal(false) != DBNull.Value;
}
}它总是检查参数是否具有默认值,并且不依赖于编译器。这可能不是百分之百正确的答案,只是我的想法。
更新0
下面是一个示例,其中参数没有默认值,但IsOptional是真的:
public static void Method([Optional]string parameter)
{
}
ParameterInfo parameterInfo = typeof(Program).GetMethod("Method").GetParameters()[0];
//Is true
bool isOptional = parameterInfo.IsOptional;
//Is false
bool hasDefaultValue = parameterInfo.HasDefaultValue;发布于 2013-04-24 10:58:12
Danny和vvs0205准确地说明了不同之处,即IsOptional总是依赖于编译器,并检查参数是否是一个可选参数,其默认值是指定的,使用HasDefaultValue。
bool isOptional = parameterInfo.IsOptional;
bool isOptionalWithADefaultValue = parameterInfo.HasDefaultValue; //.NET 4.5
bool isOptionalWithADefaultValue = (p.Attributes & ParameterAttributes.HasDefault) == ParameterAttributes.HasDefault; //.NET 4 and below从这里取走 (捕获其他一些无文档的技术来获得线程中的相同信息)
发布于 2013-04-24 08:32:47
使用"a等于b;c等于d“不能得出”它们是相同的“的结论,例如:
int[] a = new[] { 0, 1, 5 };
var c = a.Where(n => n < 2).ToArray();
var d = a.Where(n => n < 3).ToArray();
//you can't say "2 == 3" even c equals to d in sequence好,回到主题,当前一个可选参数总是有一个默认值,这个结论是正确的。但是AFAIK它是无文档的行为,这意味着编译器可能将其行为/实现更改为可选参数。因此,如果要检查(通过反射)参数是否为可选参数,请使用.IsOptional属性。如果您想要检查它是否有默认值(可能由某些属性标记,例如DefaultValue )?使用.HasDefaultValue属性。听起来像是多余的话,但这是真的。
https://stackoverflow.com/questions/16186694
复制相似问题