没有拳击通用解析方法 [英] Generic Parse Method without Boxing

查看:132
本文介绍了没有拳击通用解析方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写一个转换,并返回从NamedValueCollection一个强类型值的通用Parse方法。我尝试了两种方法,但是这两种方法都经历装箱和拆箱来获取值。有谁知道一个方法来避免装箱?如果您看到这个在生产中,你会不喜欢它,是多么糟糕它的性能。



Usuage:

  VAR ID = Request.QueryString.Parse< INT>(ID); 



尝试#1:

 公共静态牛逼解析< T>(这NameValueCollection中山坳,串键)
{
字符串值= COL [关键]

如果(string.IsNullOrEmpty(值))
返回默认值(T);

如果(typeof运算(T)== typeof运算(INT))
{
//返回int.Parse(值); //不能转换INT至T
//回报(T)int.Parse(值); //不能转换INT至T
回报率(T)(对象)int.Parse(值); //作品,但框
}
如果(typeof运算(T)== typeof运算(长))
{
回报率(T)(对象)long.Parse(值); //作品,但框
}


返回默认值(T);
}



尝试#2(使用反射):

 公共静态牛逼解析< T>(这NameValueCollection中山坳,串键)
{
字符串值= COL [关键]

如果(string.IsNullOrEmpty(值))
返回默认值(T);


{
VAR parseMethod = typeof运算(T).GetMethod(解析,新类型[] {typeof运算(字符串)});

如果(parseMethod == NULL)
返回默认值(T);

//还是拳击,因为调用返回一个对象
VAR parsedVal = parseMethod.Invoke(空,新的对象[] {值});
回报率(T)parsedVal;
}
//没有正确的解析方法发现
赶上(AmbiguousMatchException)
{
}

返回默认值(T);
}


解决方案

我觉得你是在估算拳击/拆箱的影响。解析方法将有一个更大的开销(字符串分析),矮化拳击开销。此外所有的if语句会产生更大的影响。反映了所有的影响最大。



我不希望看到这种代码在生产中,因为有那么这是一种更清洁的方式。主要的问题,我与它是大量的if语句,你需要覆盖所有案件的事实,有人可以通过任何旧的类型吧。



什么我会做的是写每种类型我想解析解析函数(如parseInt函数())。它更清晰,这是很好定义了什么功能会尽量做到。还短的静态方法,编译器更可能是内联它们,保存函数调用。



我觉得这是仿制药的不良应用,任何特殊的理由做这种方式?


I am trying to write a generic Parse method that converts and returns a strongly typed value from a NamedValueCollection. I tried two methods but both of these methods are going through boxing and unboxing to get the value. Does anyone know a way to avoid the boxing? If you saw this in production would you not like it, how bad is it for performance?

Usuage:

var id = Request.QueryString.Parse<int>("id");

Attempt #1:

public static T Parse<T>(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);
}

Attempt #2 (using reflection):

public static T Parse<T>(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);
}

解决方案

I think you are over estimating the impact of the boxing/unboxing. The parse method will have a much bigger overhead (string parsing), dwarfing the boxing overhead. Also all the if statements will have a bigger impact. Reflection has the biggest impact of all.

I'd would not like to see this kind of code in production, as there is a cleaner way of doing it. The major problem I have with it is the large number of if statements you will need to cover all cases and the fact that someone could pass any old type to it.

What I would do is write a parse function for each type I want to parse (ie ParseInt()). It's clearer and it is well defined what the function will try to do. Also with short static methods, the compiler is more likely to inline them, saving a function call.

I think this is a bad application of generics, any particular reason for doing it this way?

这篇关于没有拳击通用解析方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆