2013-08-02 163 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