C#-Enum参数的DefaultValue和RawDefaultValue的意外差异
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#-Enum参数的DefaultValue和RawDefaultValue的意外差异,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2282字,纯文字阅读大概需要4分钟。
内容图文
![C#-Enum参数的DefaultValue和RawDefaultValue的意外差异](/upload/InfoBanner/zyjiaocheng/684/3502b94946f341e79e4bb175d8fe1db3.jpg)
考虑以下示例:
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:这不是错误,而是功能…
如您在文档中所见,RawDefaultValue支持仅反射上下文,而DefaultValue不支持.
现在,如果我们检查这两种方法的源代码,我们将看到它使用bool raw标志调用System.Reflection.MdConstant的方法GetValue方法.
由于System.Reflection希望根据其所处的上下文为您提供罐中的“最佳”信息,因此,宁愿为您提供一个枚举,而不是原始值(原始值可以从枚举字段中得出,反之则不不起作用).
现在我们可以在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 });
至于支持从RawDefaultValue返回Bb的Mono,这意味着Mono不支持仅反射上下文的DefaultValue,或者它可以某种方式从可能在不同体系结构中的Assembly中创建Type的实例-这非常不太可能.
内容总结
以上是互联网集市为您收集整理的C#-Enum参数的DefaultValue和RawDefaultValue的意外差异全部内容,希望文章能够帮你解决C#-Enum参数的DefaultValue和RawDefaultValue的意外差异所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。