gpt4 book ai didi

c# - 枚举参数的 DefaultValue 和 RawDefaultValue 的意外差异

转载 作者:行者123 更新时间:2023-11-30 15:20:06 25 4
gpt4 key购买 nike

考虑以下示例:

class Program
{
static void Main(string[] args)
{
foreach(var par in typeof(A).GetMethod("Method").GetParameters())
{
Console.WriteLine("Def {0}, RawDef {1}",
par.DefaultValue, par.RawDefaultValue);
}
}
}

class A
{
public void Method(int a = 5, B b = B.b){}
}
enum B
{
a = 0, b = 1
}

根据 RawDefaultValue 的文档和 DefaultValue , 在 StackOverflow 的支持下,这两种访问默认值的方法应该返回相同的数据。

但是,我得到以下输出:

Def 5, RawDef 5
Def b, RawDef 1

因此,显然,RawDefaultValue 删除了关于参数是枚举类型的信息。

我的问题:这是一个错误还是文档的另一部分证明了这一点?

有趣的事实:在 Mono 上它返回

Def 5, RawDef 5
Def b, RawDef b

最佳答案

tl;dr:这不是错误,而是一个功能...

如您在文档中所见,RawDefaultValueDefaultValue 时支持仅反射上下文没有。

现在,如果我们检查这两个方法的源代码,我们将看到它使用 bool 调用 System.Reflection.MdConstant 的方法 GetValue 方法原始标志。

由于 System.Reflection 想要根据其所在的上下文为您提供 jar 头中的“最佳”信息,因此它宁愿为您提供一个 enum 而不是一个原始值(原始值可以从enum字段中得出,反之则不行)。

现在我们可以在 System.Reflection.MdConstant.GetValue 中看到:

if (fieldType.IsEnum && raw == false)
{
...
switch (corElementType) //The actual enum value
{
...
case CorElementType.I4:
defaultValue = *(int*)&buffer;
break;
...
}
return RuntimeType.CreateEnum(fieldType, defaultValue);
}

在你的例子中返回 B.b//= 1

但是调用 RawDefaultValue 会使该标志变为 false,这使得它:

switch (corElementType)
{
...
case CorElementType.I4:
return *(int*)&buffer;
...
}

在您的情况下返回 1

如果您尝试使用 Reflection(因为它是内部的)调用 System.RuntimeType.CreateEnum,并加载 仅反射上下文 Assembly 你会得到一个InvalidOperationException:

//Change to 'Assembly.Load' so the last line will not throw.
Assembly assembly = Assembly.ReflectionOnlyLoad("DllOfB");

Type runtimeType = Type.GetType("System.RuntimeType");
MethodInfo createEnum = runtimeType.GetMethod("CreateEnum", /*BindingFlags*/);

MethodInfo getRuntimeType = typeof(RuntimeTypeHandle).GetMethod("GetRuntimeType", /*BindingFlags*/);
Type bType = assembly.GetType("DllOfB.B");

//Throws 'InvalidOperationException':
object res = createEnum.Invoke(null, new [] { getRuntimeType.Invoke(bType.TypeHandle, new object[]{}), 1 });

至于Mono支持从RawDefaultValue返回B.b表示Mono 不支持仅反射上下文的 DefaultValue 或者它可以以某种方式从 创建 Type 的实例Assembly 可能位于不同的体系结构中 - 这是非常不可能的。

关于c# - 枚举参数的 DefaultValue 和 RawDefaultValue 的意外差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40887723/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com