2014-03-25 110 views
2

獲取字符串並將其解析爲T中給出的類型的泛型函數。我可以使所有工作除了返回。我有一個bool,想把它變成T? T是bool。根據泛型方法中的類型調用方法

public T? F<T>() where T : struct 
{ 
    var s= GetAString(); 
    if(s==null) return null; 
    if(typeof(T) == typeof(bool)) 
    { 
     var b = bool.Parse(s); 
     return ?? 
    } 
    if(typeof(T) == typeof(int)) 
    { 
     var i = int.Parse(s); 
     return ?? 
    } 
    ... 
} 

返回b不起作用

回報(T?)B不工作

回報新款T?(二)

+0

我很好奇'GetAString()'的代碼看起來像 – RadioSpace

+0

它從配置數據庫返回一個字符串。該鍵作爲參數傳遞給真正的方法。它返回「42」,「True」,...當然,如果配置預期是bool(T = bool),並且它代之以包含「42」或「Foo」,則會拋出所示方法 – pm100

回答

3

這當然不是很漂亮,但雙鑄造到object然後到T?(或在這種情況下三重鑄造,因爲b實際上是bool而不是bool?)將工作:

if(typeof(T) == typeof(bool)) 
{ 
    var b = bool.Parse(s); 
    return (T?)(object)(bool?)b; 
} 
if(typeof(T) == typeof(int)) 
{ 
    var i = int.Parse(s); 
    return (T?)(object)(int?)i; 
} 

但是,我通常會避免編寫這種類型的代碼。這首先打破了使用泛型的目的。畢竟,如果您必須針對您可能接受的每種類型參數編寫不同的策略,這不是通用解決方案。


另一種解決方案是創建「解析器」類像這樣:

public interface IParser { 
    object Parse(string s); 
} 

public class BoolParser : IParser { 
    public object Parse(string s) { 
     return bool.Parse(s); 
    } 
} 

public class IntParser : IParser { 
    public object Parse(string s) { 
     return int.Parse(s); 
    } 
} 

而且在這樣的字典靜態註冊他們:

private static Dictionary<Type, IParser> parsers = new Dictionary<Type, IParser>(); 
public static void Register<TResult, TParser>() 
    where TResult : struct 
    where TParser : IParser, new() 
{ 
    parsers.Add(typeof(TResult), new TParser()); 
} 

... 

Register<bool, BoolParser>(); 
Register<int, IntParser>(); 

現在你可以寫您的F方法是這樣的:

public T? F<T>() where T : struct 
{ 
    var s = GetAString(); 
    if (s == null) 
     return null; 
    var t = typeof(T); 
    if (parsers.ContainsKey(t)) 
     return (T)parsers[t].Parse(s); 
    else 
     throw new Exception("Specified type is not supported"); 
} 
+0

也許你是對。我想避免重複代碼和其他各種原因,我需要一個返回T的方法? (它適合於代碼庫中的T形孔) – pm100

+0

TY - OMG可以工作,但是如何解決它(除了通過SO)。我想爲什麼你的代表是10x我 – pm100

+0

@ pm100很高興我能幫上忙。 '(bool?)'是需要轉換(這在技術上是一種轉換,而不是一種轉換)從不可爲空到可空類型。第二個'(對象)'需要[''可空值](http://msdn.microsoft.com/en-us/library/ms228597.aspx),它將它放在堆上。最後的'(T?)'將它解開爲泛型類型,它從堆中移除並驗證值的類型。類型檢查器不夠聰明,無法驗證'(T?)b'是否安全,因此'(T?)(對象)'有效地使類型檢查器短路。 –