【发布时间】:2019-01-07 20:01:53
【问题描述】:
我有一个将表达式作为参数的函数。表达式的类型是Func<int?>。但是当表达式被计算时,可以为空的 int 被解包。
参见以下代码:
using System;
using System.Linq.Expressions;
public class Program
{
public static void Main()
{
var asd = new Asd() { Id = 1 };
Do(() => asd.Id);
Console.Read();
}
private static void Do<T>(Expression<Func<T>> expr)
{
var tType = typeof(T);
var type = expr.Compile()().GetType();
Console.Write($"T = {tType.Name}, obj type = {type.Name}");
}
class Asd
{
public int? Id { get; set; }
}
}
控制台显示以下输出:
T = Nullable`1, obj type = Int32
为什么会发生这种情况,我该如何避免这种情况? 不幸的是,我无法提供 dotnetfiddle,因为此代码不在 dotnetfiddle 中运行。可能是因为表情。
//编辑:
明确一点:我需要属性 Id 的类型为int?,并且我需要编译并执行该函数。这里的问题出现在更大的代码中。此代码只是拥有可运行示例所需的最少代码集。
最好的问候
//编辑2:
原来我的小例子也产生了错误,这让我认为它显示了我的实际问题。但当然不是。
我使用GetType() 向您展示函数返回值不是Nullable<int> 类型,而是int。根据 cmets 中提供的链接,GetType() 会导致可空对象的拆箱,从而返回基础类型。
我真正的问题是另一个可能有类似原因的问题。
我使用var valueExpr = Expression.Constant(valueFromImport); 创建了一个可以为空的值int? valueFromImport = ... 的常量表达式。后来我设置了一个表达式来将常量分配给一个可为空的属性。失败并出现异常:
System.ArgumentException: "Expression of type 'System.Int32' cannot be used for assignment to type 'System.Nullable`1[System.Int32]'"
问题是,Expression.Constant 似乎也将可空值拆箱。当我使用var valueExpr = Expression.Constant(valueFromImport, typeof(T)); 时,一切都按预期工作。
【问题讨论】:
-
你正在编译它然后调用它。删除一组
() -
只需将
Console.Write($"T = {tType.Name}, obj type = {type.Name}");替换为Console.Write($"T = {tType}, obj type = {type.Name}");,您将获得有关泛型参数类型的信息(提示:您将获得Nullable'1[Int32]而不仅仅是Nullable'1)。 -
如果您通过删除
interpolated string和不必要的()来修复它,此代码在 .NET Fiddle 中可以正常工作 -
The problem is that the console shows int32 for the function's result.阅读我给你的链接。特别阅读问题。尤其要阅读其中的 MSDN 引用。 粗体中的位。我怀疑这可能与您的情况有关并可以解释。
标签: c# expression nullable func