這當然不是很漂亮,但雙鑄造到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");
}
我很好奇'GetAString()'的代碼看起來像 – RadioSpace
它從配置數據庫返回一個字符串。該鍵作爲參數傳遞給真正的方法。它返回「42」,「True」,...當然,如果配置預期是bool(T = bool),並且它代之以包含「42」或「Foo」,則會拋出所示方法 – pm100