2013-06-28 26 views
0

我跟着解決此網站,提出了以下方法的建議:類型「字符串」必須是一個非空值類型,以便用它作爲參數「T」在通用類型或方法

public static T? GetElementValue<T>(this XElement xElement, string s) 
    where T : struct, IComparable 
{ 
    var result = new Nullable<T>(); 

    try 
    { 
     if (string.IsNullOrEmpty(s) || s.Trim().Length > 0 || xElement.IsEmpty) 
      return result; 

     var element = xElement.Element(s); 

     if (element == null || element.IsEmpty) 
      return result; 

     var conv = TypeDescriptor.GetConverter(typeof(T)); 
     result = (T)conv.ConvertFrom(element.Value); 
    } 
    catch (Exception ex) 
    { 
      ex.Message.WriteAsError(); 
    } 

    return result; 
} 

但是當我嘗試使用它與string我仍然得到以下錯誤: 類型'字符串'必須是一個不可爲空的值類型爲了使用它作爲泛型類型或方法中的參數'T'

有人可以告訴我爲什麼? Thx

+2

有幾件事要注意:1)而不是檢查'string.IsNullOrEmpty(s)|| s.Trim()。Length> 0',而是隻檢查String.IsNullOrWhitespace(s)'。 2)你應該檢查變量'xElement',看它在使用之前是否爲空(因爲它可以)。 3)如果一個方法要吞噬異常,通常你想使它成爲'bool TryGetElementValue (...,out T?result){...}',這是首選模式(返回bool,將其命名爲與* Try *,並有一個out參數)。 –

+2

您可能想限制IConvertible接口而不是IComparable接口,而不是IComparable接口。 – Magnus

+0

我想用同樣的方法返回一個Nullable對象嗎? q.GetElementValue (「myIntCanBeNull」); –

回答

7

您已通過

where T : struct 

struct限制限制了您T參數意味着只有值類型可以爲T供應。 string(更確切地說,System.String)然而,是一個類,一個引用類型。

刪除該限制將不會很微不足道,因爲您使用T作爲T?,即可以爲空TNullable<T>反過來只接受值類型。

您必須對您是否允許引用類型決定 - 如果你想限制T引用類型,使用class約束,而不是struct(並刪除?T?,引用類型總是可爲空的他們自己的)。如果您想允許值類型和引用類型,則不能創建可空的T版本。如果您需要所有這些信息,請擴展您對環境的描述,以便我們幫助您找到更好的解決方案。

3

因爲您將T限制爲值類型 - where T : struct, IComparable,而字符串是引用類型。

+4

我不明白爲什麼這個答案值得downvote –

+0

都不。 +1 ...... –

+0

我也很困惑! – NDJ

3

一個字符串不是一個值類型,它是一個不可變的引用類型,因此它違反了T所必須的一般約束條件,即T必須是struct

查看string型號文檔,瞭解有關string的更多詳細信息。

相關問題