为什么C#将这些设置为相等?
typeof(int).GetType() == typeof(int?).GetType()
在我投射的地方编写表达式树时出现问题
List<int?> ids = JsonConvert.DeserializeObject<List<int?>>(filter.Value?.ToString());
var filterField = filter.PropertyName;
var method = ids.GetType().GetMethod("Contains");
return Expression.Call(Expression.Constant(ids), method, member);
生成此错误
系统。ArgumentException:类型为"System"的表达式。Int32不能用于"System"类型的参数。可为空的
1[System.Int32]' of method 'Boolean Contains(System.Nullable
1[System.Int32](
在发送到表达式树之前,是否有方法检查类型?
我尝试检查int
和int?
的类型,对于以下检查,两者都返回true:
bool isIntNull = type == typeof(int?).GetType();
为什么C#将这些设置为相等?
因为它们是相等的。
typeof(int)
通过编译器生成RuntimeType
实例
typeof(int?)
通过编译器生成一个不同的RuntimeType
实例
在任何RuntimeType
实例上调用GetType()
都会返回类型System.RuntimeType
我想你想要
typeof(int) == typeof(int?)
和
bool isIntNull = type.Equals(typeof(int?));
证明:
Console.WriteLine(typeof(int));
Console.WriteLine(typeof(int?));
Console.WriteLine(typeof(int).GetType());
Console.WriteLine(typeof(int?).GetType());
输出:
System.Int32
System.Nullable`1[System.Int32]
System.RuntimeType
System.RuntimeType
typeof(X)
运算符始终返回一个代表类型X
的Type
对象。GetType()
方法返回调用它的对象的运行时类型。因此,如果您有表达式typeof(X).GetType()
,则该表达式的第一部分将始终返回一个Type
实例,而该表达式的第二部分将总是返回一个代表类型Type
的Type
对象,无论X
是什么。您需要比较typeof(int)
和typeof(int?)
,它们是不同的。
我认为,表达式树的问题在于member
变量是int
类型的Expression
,而不是int?
。你发布的代码没有显示它的来源,但我认为以下内容会对你有所帮助:
return Expression.Call(Expression.Constant(ids), method, Expression.Convert(member, typeof(int?)));
在这里搜索答案并尝试所有内容后,找到了这个。
bool isIntNull = member.Type.IsGenericType && member.Type.GetGenericTypeDefinition() == typeof(Nullable<>);
我在将未知运行时数据类型的数据提取为已知数据类型时遇到了同样的问题-我通过这种方式解决了这个问题。
public bool CompareDataType<T>(Type runtimedatatype)
{
Type KT = typeof(T);
return runtimedatatype.Equals(KT) || runtimedatatype.Equals(Nullable.GetUnderlyingType(KT));
}
int? output = null;
object RunTimeData = (object)((int)0);
if (CompareDataType<int?>(RunTimeData.GetType()))
output = (int?)RunTimeData;
或者,你可以创建Object的扩展(这就是我最后使用的(
public static class ObjectTypeIsEqual
{
public static bool CompareDataType<T>(this object input)
{
Type ObjectType = input.GetType();
Type CompareType = typeof(T);
return ObjectType.Equals(CompareType) || ObjectType.Equals(Nullable.GetUnderlyingType(CompareType));
}
}
int? output = null;
object RunTimeData = (object)((int)0);
if (RunTimeData.CompareDataType<int?>())
output = (int?)RunTimeData;