2013-08-02 165 views
18

我需要知道如何将int转换为可空int。但是,我不断收到一个错误“二进制运算符Equal没有为类型'System.Nullable`1 [System.Int32]'和'System.Int32'定义。”任何解决方案它需要是Microsoft SQL Server的可空int类型。将int转换为可为空的int?

somevalue = Expression.Constant(something.GetValue(some,null).To<Nullable<System.Int32>>()); 

public static T To<T>(this object obj) 
    { 
     Type t = typeof(T); 
     Type u = Nullable.GetUnderlyingType(t); 

     if (u != null) 
     { 
      if (obj == null) 
       return default(T); 

      return (T)Convert.ChangeType(obj, u); 
     } 
     else 
     { 
      return (T)Convert.ChangeType(obj, t); 
     } 
    }' 
+1

什么'something.GetValue'的返回类型?它看起来像你要做很多工作,应该更简单... –

+0

错误是编译器错误还是运行时错误?我试图用各种输入来运行你的方法,我一直没能得到任何错误。如果您遇到运行时异常,请提供堆栈跟踪。 –

+0

返回类型应该是int ?.问题是我得到通过一个int?这是来自数据库的值,然后该函数返回一个int,然后我需要转换回int ?.原因是因为我试图做一个动态查询。另外somevalue是一个变种!不是int?并且必须永远是一个变种,这是不能改变的,所以我不能像人们所建议的那样施放。 – user2582770

回答

22

To代码似乎您试图建构可空类型的Constant给非可空类型的值时,但就是不是在所有正确的方式去了解这个。您尝试这样做的方式表明您对盒装值类型的工作方式存在误解。

该错误消息表明您正在构建一个二元运算符表达式树节点,该节点具有作为其操作数的可为空的int类型的表达式节点和int类型的表达式节点。这不合法;他们必须是都是可以为空。你应该做的是将非空的int表达式树节点包装在一个Convert表达式树节点中,该节点将其转换为可为空的int,然后将传递给二元运算符表达式树节点构造函数。

也就是说,这是错误的:

var someIntExpr = Expression.Constant(123, typeof(int)); 
var someNubIntExpr = Expression.Constant(null, typeof(int?)); 
var badEq = Expression.Equal(someIntExpr, someNubIntExpr); 

这是正确的:

var goodEq = Expression.Equal(Expression.Convert(someIntExpr, typeof(int?)), someNubIntExpr); 

那么,为什么你在做什么错?

您有一个方法To<T>,它返回一个T。它正确接受int并返回相应的int?。那又怎么样?您将其传递给Expression.Constant,将可空的int 放入盒装的int中,然后将其作为常数。你相信有这样的事情,像盒装可空值类型,但没有!可以为空的值类型可以将空值引用或装箱的非空值类型框。

所以你也可以通过来解决你的问题,首先不要做任何这种疯狂的东西。如果手头有盒装int,并且需要一个可以为空的类型的常量表达式树节点,则只提供类型

Expression.Constant(someBoxedIntValue, typeof(int?)) 

完成。所以:结束了,你有两个解决方案:

  • 如果你手上有装箱的int,通过它,你想要的Constant出厂的空值类型,或
  • ,如果你有一个表达式节点键入int,然后使用Convert表达式节点工厂,并将其传递给所需的类型。

两者都会返回正确类型的表达式节点,以便与另一个可为空的int进行比较。

+0

嘿谢谢你的回复,我想你可能是对的。但我不知道如何将这个实现到我当前的代码上。你可以举个例子来说明这个var somevalue = Expression.Constant(something.GetValue(some,null).To >());我是否只需要更改此代码? – user2582770

+0

你的天才!有效! – user2582770

+2

@ user2582770:我不是天才,但我是写了很大一部分代码的人。 :-) 恭喜你弄明白了。 –

3
int i = 1; 
int? k; 
k = i as int?; 

这样你就可以转换i这是一个int为可空INT)

int?Nullable<int>的短版。

4
int test = 0; // set int 

int? num = test; // convert test to a nullable int 

num = null; // set num as null 
16

通常情况下,你使用强制转换的intint?

int? myNullable = (int?) 15; 
int myInt = (int) myNullable; 
2

是否有更简单的方法可以解决这个问题?

int i; 
int? temp = int.TryParse(<your value>, out i) ? (int?)i : null; 
2

你在这里。可以为空的原始解决方案的通用字符串。

int? n = " 99 ".ToNullable<int>(); 

/// <summary> 
/// Developed by Taylor Love 
/// </summary> 
public static class ToNullableStringExtension 
{ 
    /// <summary> 
    /// <para>More convenient than using T.TryParse(string, out T). 
    /// Works with primitive types, structs, and enums. 
    /// Tries to parse the string to an instance of the type specified. 
    /// If the input cannot be parsed, null will be returned. 
    /// </para> 
    /// <para> 
    /// If the value of the caller is null, null will be returned. 
    /// So if you have "string s = null;" and then you try "s.ToNullable...", 
    /// null will be returned. No null exception will be thrown. 
    /// </para> 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="p_self"></param> 
    /// <returns></returns> 
    public static T? ToNullable<T>(this string p_self) where T : struct 
    { 
     if (!string.IsNullOrEmpty(p_self)) 
     { 
      var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)); 
      if (converter.IsValid(p_self)) return (T)converter.ConvertFromString(p_self); 
      if (typeof(T).IsEnum) { T t; if (Enum.TryParse<T>(p_self, out t)) return t;} 
     } 

     return null; 
    } 

https://github.com/Pangamma/PangammaUtilities-CSharp/tree/master/src/StringExtensions