【发布时间】:2016-05-27 21:16:41
【问题描述】:
我在一个 Web 应用程序中遇到了 NullReferenceException,并花费了大量时间来实际发现问题。我用控制台应用程序重现了这个问题。您可以尝试按原样运行以下代码-
using System;
using System.Linq.Expressions;
namespace Expression
{
public struct ValueType { }
public class ReferenceType { }
public class MyClass
{
public ReferenceType ReferenceType { get; set; }
public ValueType ValueType { get; set; }
}
class Program
{
public static string GetPropertyName<T>(Expression<Func<T, object>> expression)
{
return (expression.Body as MemberExpression).Member.Name;
}
static void Main(string[] args)
{
MyClass c1 = new MyClass();
MyClass c2 = new MyClass();
Console.WriteLine(GetPropertyName<MyClass>(x => x.ReferenceType));
// No Error
Console.WriteLine(GetPropertyName<MyClass>(x => x.ValueType));
// System.NullReferenceException
}
}
}
所以问题是通用函数 GetPropertyName 在作为具有引用类型属性的函数的参数给出的表达式但值类型属性导致System.NullReferenceException(expression.Body as MemberExpression).Member 时起作用。
所以我的问题是为什么它适用于引用类型而不是值类型?
【问题讨论】:
-
我相信如果“expression.Body”的类型不是“MemeberExpression”,就会发生这种情况。
-
@NexTerren 它是
UnarayExpression,问题是,为什么? -
@JonathonReinhart 我觉得有点不一样。
-
总结重复,是因为你的表达式只接受
object作为返回类型,所以值类型必须装箱,这会导致Convert(x.ValueType)的UnarayExpression,如果你检查了那个表达式的.Operand,你会发现你在寻找你的MemberExpression(或者只是让它接受一个泛型而不是对象,这样它就不需要装箱了)。
标签: c#