Why does C# set these equal?
typeof(int).GetType() == typeof(int?).GetType()
The problem occurs when writing expression trees where I cast the
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);
generates this error
System.ArgumentException: Expression of type 'System.Int32' cannot be used for parameter of type 'System.Nullable
1[System.Int32]' of method 'Boolean Contains(System.Nullable
1[System.Int32])
Is there a way to check the type before sending to the expression tree?
I tried checking the types of int
and int?
and both return true for the following check:
bool isIntNull = type == typeof(int?).GetType();
Why does C# set these equal?
Because they ARE equal.
typeof(int)
generates a RuntimeType
instance by the compiler
typeof(int?)
generates a different RuntimeType
instance by the compiler
calling GetType()
on any RuntimeType
instance returns the type System.RuntimeType
I think you want
typeof(int) == typeof(int?)
and
bool isIntNull = type.Equals(typeof(int?));
Proof:
Console.WriteLine(typeof(int));
Console.WriteLine(typeof(int?));
Console.WriteLine(typeof(int).GetType());
Console.WriteLine(typeof(int?).GetType());
output:
System.Int32
System.Nullable`1[System.Int32]
System.RuntimeType
System.RuntimeType
The typeof(X)
operator always returns a Type
object representing the type X
. The GetType()
method returns the runtime type of the object it is called on. So if you have the expression typeof(X).GetType()
the first part of the expression will always return a Type
instance, and the second part of that expression will always return a Type
object representing the type Type
, no matter what X
is. You want to compare typeof(int)
to typeof(int?)
, which are different.
I think, whats wrong with your expression tree is that the member
variable is an Expression
of type int
instead of int?
. The code you posted didn't show where it is coming from, but I think the following would help you:
return Expression.Call(Expression.Constant(ids), method, Expression.Convert(member, typeof(int?)));
搜索答案并尝试此处的所有内容后,发现了这一点。
bool isIntNull = member.Type.IsGenericType && member.Type.GetGenericTypeDefinition() == typeof(Nullable<>);
I have the same problem extracting data of an unknown runtime datatype to a known datatype - I solved the problem this way.
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;
Alternatively you can create an extension of Object (which is what I went with in the end)
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;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.