Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net ParameterInfo.IsOptional和ParameterInfo.HasDefaultValue之间的差异?_.net_Reflection_Default Value_Optional Parameters_Parameterinfo - Fatal编程技术网

.net ParameterInfo.IsOptional和ParameterInfo.HasDefaultValue之间的差异?

.net ParameterInfo.IsOptional和ParameterInfo.HasDefaultValue之间的差异?,.net,reflection,default-value,optional-parameters,parameterinfo,.net,Reflection,Default Value,Optional Parameters,Parameterinfo,它们听起来都很相似。从msdn: 获取一个值,该值指示此参数是否为可选参数 此方法依赖于可选的元数据标志。此标志可以是 由编译器插入,但编译器没有义务这样做 此方法使用ParameterAttributes的可选标志 统计员 (在.NET 4.5中新增) 获取一个值,该值指示此参数是否具有默认值 他们不一样吗?我做了快速测试: public void A(string value) { } public void B(string value, int i = -1) { } 我写道:

它们听起来都很相似。从msdn:

获取一个值,该值指示此参数是否为可选参数

此方法依赖于可选的元数据标志。此标志可以是 由编译器插入,但编译器没有义务这样做

此方法使用ParameterAttributes的可选标志 统计员

(在.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

使用“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();
//你不能说“2==3”,即使c在序列中等于d

好,回到主题,当前一个可选参数总是有一个默认值,这个结论是正确的。但它是未记录的行为,这意味着编译器可能会将其行为/实现更改为可选参数。因此,如果要检查(通过反射)参数是否为可选参数,请使用
.IsOptional
属性。如果要检查它是否具有默认值(可能由某些属性标记,例如DefaultValue?只是可能),请使用
.HasDefaultValue
属性。听起来像是多余的词,但这是真的。

如果我们看看
isonational
的实现,我们会看到:

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
为真:

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;

Danny Chen和VVS00205准确地说明了差异,即
IsOptional
始终依赖于编译器,要检查该参数是否是指定默认值的可选参数,请使用
hasdaultvalue

bool isOptional = parameterInfo.IsOptional;

bool isOptionalWithADefaultValue = parameterInfo.HasDefaultValue; //.NET 4.5

bool isOptionalWithADefaultValue = (p.Attributes & ParameterAttributes.HasDefault) == ParameterAttributes.HasDefault; //.NET 4 and below

(捕捉一些其他未记录的技术,以在该线程中获得相同的结果)

downvoter,如果我的问题很愚蠢,请给出答案,或者留下评论,以便我能以更好的方式提问您是在谈论PropertyInfo(标题)还是ParameterInfo(问题)?@MarcGravell哦,天哪,打败我!我会编辑它的,我明白了,而且我知道它肯定是不能用的(我忽略了它)。这就是为什么我提出这个问题。我刚才说了一个我能想到的场景,
hasdaultvalue
可能不同于
isonational
,但事实证明并非如此。社区这样问,因为它听起来像一个基本的
2!=3
:)是的,
HasDefaultValue
是一种方法,但是在.NET4中,你可以使用
p.Attributes&ParameterAttributes。HasDefault
方法
ParameterAttributes。HasDefault
也取决于编译器。你说它不是100%正确的意思是什么?答案只是我的想法。你问他们为什么这么做?我不能确切回答他们为什么这样做,所以我只能假设。啊,现在我明白了,但你的措辞并不那么清楚。请找到我的编辑
bool isOptional = parameterInfo.IsOptional;

bool isOptionalWithADefaultValue = parameterInfo.HasDefaultValue; //.NET 4.5

bool isOptionalWithADefaultValue = (p.Attributes & ParameterAttributes.HasDefault) == ParameterAttributes.HasDefault; //.NET 4 and below