他们听起来都很相似。来自msdn:
ParameterInfo.IsOptional
获取一个值,该值指示此参数是否可选。
此方法取决于可选的元数据标志。该标志可以是
由编译器插入,但编译器没有义务这样做。
此方法利用ParameterAttributes的Optional标志
枚举器。
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新在.NET 4.5中引入了
HasDefaultValue
? 最佳答案
如果我们看一下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;
}
}
它总是检查参数是否具有默认值,并且不依赖于编译器。这可能不是100%正确的答案,只是我的想法。
更新0
这是参数没有默认值但
IsOptional
为true的示例: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;