我正在尝试编写一个通用的Parse方法,该方法转换并返回NamedValueCollection中的强类型值.我尝试了两种方法,但这两种方法都通过装箱和拆箱来获得价值.有谁知道避免拳击的方法?如果你在生产中看到这个你会不喜欢它,它的性能有多糟糕?
Usuage:
var id = Request.QueryString.Parse("id");
尝试#1:
public static T Parse(this NameValueCollection col, string key) { string value = col[key]; if (string.IsNullOrEmpty(value)) return default(T); if (typeof(T) == typeof(int)) { //return int.Parse(value); // cannot convert int to T //return (T)int.Parse(value); // cannot convert int to T return (T)(object)int.Parse(value); // works but boxes } if (typeof(T) == typeof(long)) { return (T)(object)long.Parse(value); // works but boxes } ... return default(T); }
尝试#2(使用反射):
public static T Parse(this NameValueCollection col, string key) { string value = col[key]; if (string.IsNullOrEmpty(value)) return default(T); try { var parseMethod = typeof(T).GetMethod("Parse", new Type[] { typeof(string) }); if (parseMethod == null) return default(T); // still boxing because invoke returns an object var parsedVal = parseMethod.Invoke(null, new object[] { value }); return (T)parsedVal; } // No Proper Parse Method found catch(AmbiguousMatchException) { } return default(T); }
Robert C. Ba.. 34
public static T Parse(this NameValueCollection col, string key) { return (T)Convert.ChangeType(col[key], typeof(T)); }
我不完全确定ChangeType框是不是(我想阅读文档会告诉我,但我现在时间紧迫),但至少它摆脱了所有类型检查.虽然拳击开销不是很高,所以我不会太担心它.如果您担心运行时类型的一致性,我会将函数编写为:
public static T Parse(this NameValueCollection col, string key) { T value; try { value = (T)Convert.ChangeType(col[key], typeof(T)); } catch { value = default(T); } return value; }
这样,如果由于某种原因无法转换值,函数将不会弹出.这意味着,当然,您必须检查返回的值(无论如何您都必须这样做,因为用户可以编辑查询字符串).
public static T Parse(this NameValueCollection col, string key) { return (T)Convert.ChangeType(col[key], typeof(T)); }
我不完全确定ChangeType框是不是(我想阅读文档会告诉我,但我现在时间紧迫),但至少它摆脱了所有类型检查.虽然拳击开销不是很高,所以我不会太担心它.如果您担心运行时类型的一致性,我会将函数编写为:
public static T Parse(this NameValueCollection col, string key) { T value; try { value = (T)Convert.ChangeType(col[key], typeof(T)); } catch { value = default(T); } return value; }
这样,如果由于某种原因无法转换值,函数将不会弹出.这意味着,当然,您必须检查返回的值(无论如何您都必须这样做,因为用户可以编辑查询字符串).
我认为你过度估计拳击/拆箱的影响.解析方法将有更大的开销(字符串解析),使拳击开销相形见绌.此外,所有if语句都会产生更大的影响.反思对所有人产生了最大的影响.
我不希望在生产中看到这种代码,因为有一种更简洁的方法.我遇到的主要问题是需要覆盖所有案例的大量if语句以及有人可以将任何旧类型传递给它的事实.
我要做的是为我想要解析的每个类型编写一个解析函数(即ParseInt()).它更清晰,并且很好地定义了该函数将尝试做什么.此外,对于短静态方法,编译器更可能内联它们,从而保存函数调用.
我认为这是泛型的一个不好的应用,这样做的任何特殊原因?