bed*_*edo 62 .net c# dynamic nullreferenceexception
我有以下功能:
public static T TryGetArrayValue<T>(object[] array_, int index_)
{
... //some checking goes up here not relevant to question
dynamic boxed = array_[index_];
return (T)boxed;
}
Run Code Online (Sandbox Code Playgroud)
当我用以下方式调用它时,
object a = new object();
object v = TUtils.TryGetArrayValue<object>(new object[] { a }, 0);
Run Code Online (Sandbox Code Playgroud)
(T)boxed
抛出空引用异常.
除了"对象"之外,我放在那里的任何其他类型,它完全正常.
任何想法是什么,为什么它抛出异常?
编辑:我使用动态的原因是为了避免在转换类型时出现异常,例如:
double a = 123;
int v = TUtils.TryGetArrayValue<int>(new object[] { a }, 0);
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 43
我同意其他回答说这看起来像个错误的回答者.具体来说,它似乎是C#运行时绑定层中的一个错误,虽然我没有彻底调查它.
我为错误道歉.我将它报告给C#5测试团队,我们将看看它是否已经在C#5中报告和修复.(它在最近的beta版本中重现,所以它不太可能已经被报告和修复. )如果没有,修复不太可能进入最终版本.在这种情况下,我们会考虑将其用于可能的服务发布.
谢谢让我们注意到这个.如果您想要输入Connect问题来跟踪它,请随意这样做,并请包含此StackOverflow问题的链接.如果你不这样做,没问题; 测试团队将以任何方式了解它.
Ree*_*sey 14
这是动态工作原理的一个问题 - 运行时绑定程序存在转换问题System.Object
,但实际上并不是问题.
我怀疑这是因为dynamic
,在运行时,本身就是永远 System.Object
.4.7中的C#语言规范:"动态类型在运行时与对象无法区分." 因此,任何用作动态的对象都只是作为对象存储.
当您将实际实例System.Object
放入动态时,在运行时绑定解析中会出现一些导致空引用异常的内容.
但是,任何其他不起作用的System.Object
类型 - 甚至引用类型等,没有缺陷.因此,这应该为您提供正确的行为,因为实际上没有理由创建一个System.Object
可以传递的自身实例- 您总是希望某个子类具有其他类型信息.
只要您使用任何"真实"类型,这都可以正常工作.例如,以下工作,即使它已被传递并视为Object
:
public class Program
{
public static T TryGetArrayValue<T>(object[] array_, int index_)
{
dynamic boxed = array_[index_];
return (T)boxed;
}
private static void Main()
{
int p = 3;
object a = p;
var objects = new[] { a, 4.5 };
// This works now, since the object is pointing to a class instance
object v = TryGetArrayValue<object>(objects, 0);
Console.WriteLine(v);
// These both also work fine...
double d = TryGetArrayValue<double>(objects, 1);
Console.WriteLine(d);
// Even the "automatic" int conversion works now
int i = TryGetArrayValue<int>(objects, 1);
Console.WriteLine(i);
Console.ReadKey();
}
}
Run Code Online (Sandbox Code Playgroud)
这是非常奇怪的行为,它确实看起来像是一个执行中的错误dynamic
.我发现这种变化不会引发异常并确实返回对象:
public static T TryGetArrayValue<T>(object[] array, int index) where T : class
{
dynamic boxed = array[index];
return boxed as T;
}
Run Code Online (Sandbox Code Playgroud)
请注意,我必须在方法签名中添加泛型约束,因为as
只有T
作为引用类型,运算符才有效.
如果您正在寻找一种解决方法,您可以使用它(我知道它很难看):
public static T TryGetArrayValue<T>(object[] array, int index)
{
dynamic boxed = array[index];
if (typeof(T) == typeof(object))
return (T)(boxed as object);
return (T)boxed;
}
Run Code Online (Sandbox Code Playgroud)