naw*_*fal 11 .net reflection default-value optional-parameters parameterinfo
它们听起来都很相似.来自msdn:
获取一个值,该值指示此参数是否可选.
此方法取决于可选的元数据标志.编译器可以插入此标志,但编译器没有义务这样做.
此方法使用ParameterAttributes枚举器的Optional标志.
ParameterInfo.HasDefaultValue(.NET 4.5中的新增功能)
获取一个值,该值指示此参数是否具有默认值.
他们不一样吗?我做了快速测试:
public void A(string value)
{
}
public void B(string value, int i = -1)
{
}
Run Code Online (Sandbox Code Playgroud)
我写:
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
Run Code Online (Sandbox Code Playgroud)
那么它们在哪种情况下有所不同?为什么BCL HasDefaultValue新推出.NET 4.5?
如果我们看一下实施情况,IsOptional我们会看到:
public bool IsOptional
{
[__DynamicallyInvokable] get
{
return (this.Attributes & ParameterAttributes.Optional) != ParameterAttributes.None;
}
}
Run Code Online (Sandbox Code Playgroud)
它取决于元数据标志,但它是在msdn中编写的:
此方法取决于可选的元数据标志.编译器可以插入此标志,但编译器没有义务这样做.
这意味着它依赖于编译器,如果我们使用其他编译器,我们可以获得具有默认值的参数将不具有IsOptional标志.现在让我们看看HasDefaultValue属性是如何实现的:
public override bool HasDefaultValue
{
get
{
if (this.m_noMetadata || this.m_noDefaultValue)
return false;
else
return this.GetDefaultValueInternal(false) != DBNull.Value;
}
}
Run Code Online (Sandbox Code Playgroud)
它始终检查参数是否具有默认值,并且不依赖于编译器.这可能不是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;
Run Code Online (Sandbox Code Playgroud)