您的位置:首页 > 其它

什么时候应该实现String到值类型的转换器

2007-01-26 12:15 260 查看
.Net内部的值类型都提供Parse用来处理string的转换,相信在托管代码下这样转换应该是最高效的了;看上去自己实现一个string的转换对象似乎没有这个必要。但Parse方法有个缺点,除非能保证提供的string有效性要不就会发异常。有时为了保证转换错误不会影响程序会这样做:

try

{

value = Int16.Parse(str[i]);

}

catch

{}

以上代码看去并没有什么问题,但在某些场景下就是问题的根源!

有时候实现一个对象数据绑定器,数据来源于Web的提交信息。通过绑定功能可以节省大量手写代码:

Codes.OrderSearch search = BindObject<Codes.OrderSearch>("");

由于Web提供的信息都是基于String,因为通过反射根据类型进行转换;为了保证个别成员的转换错误不影响整个过程那只有加上try{}catch{}。因为组件内部是不能保证提供的String合法性,因此在转换过程抛出异常是经常的事;就是因为异常的抛出会导致BindObject的过程中性能会出现严重问题。

为了证实以上问题写了一个小小的测试用例:

static void Test1()

{

string[] str = new string[] {"2123","234s12","12123","4325","12er243","-4112" ,"3rer32","-1213","121","22342313"};

Int16 value = -1;

object converobj;

IStringConverter toint = new ToInt16();

bool ok;

Stopwatch watch = new System.Diagnostics.Stopwatch();

for (int i = 0; i < 10; i++)

{

watch.Reset();

watch.Start();

try

{

value = Int16.Parse(str[i]);

}

catch

{

value = -1;

}

watch.Stop();

Console.WriteLine("value:{0}", value!=-1?(object)value:"Error");

Console.WriteLine("System Pares Time:{0}", watch.Elapsed);

watch.Reset();

watch.Start();

converobj = toint.ConvertTo(str[i], out ok);

if (ok)

value = (Int16)converobj;

else

value = -1;

watch.Stop();

Console.WriteLine("value:{0}", value !=-1 ? (object)value : "Error");

Console.WriteLine("Custom Pares Time:{0}", watch.Elapsed);

Console.WriteLine("====================================");

decimal de = decimal.Parse("1212.45");

}

}

下页结果才能看到问题原因:

value:2123

System Pares Time:00:00:00.0000167

value:2123

Custom Pares Time:00:00:00.0014842

====================================

value:Error

System Pares Time:00:00:00.0046785

value:Error

Custom Pares Time:00:00:00.0000388

====================================

value:12123

System Pares Time:00:00:00.0000148

value:12123

Custom Pares Time:00:00:00.0000785

====================================

value:4325

System Pares Time:00:00:00.0000139

value:4325

Custom Pares Time:00:00:00.0000145

====================================

value:Error

System Pares Time:00:00:00.0050481

value:Error

Custom Pares Time:00:00:00.0000156

====================================

value:-4112

System Pares Time:00:00:00.0000153

value:-4112

Custom Pares Time:00:00:00.0000153

====================================

value:Error

System Pares Time:00:00:00.0037747

value:Error

Custom Pares Time:00:00:00.0000164

====================================

value:-1213

System Pares Time:00:00:00.0000148

value:-1213

Custom Pares Time:00:00:00.0000156

====================================

value:121

System Pares Time:00:00:00.0000142

value:121

Custom Pares Time:00:00:00.0000148

====================================

value:Error

System Pares Time:00:00:00.0034585

value:Error

Custom Pares Time:00:00:00.0000159

====================================

从结果可以看到在转换错误时所负出的代价。

因此在某些场景下使用自定义转换类还是很有必要的。

ToInt16的实现代码:

public class ToInt16 : IStringConverter

{

#region IStringConverter 成员

object IStringConverter.ConvertTo(string value, out bool succeeded)

{

succeeded = (value != null && value != "");

if (!succeeded)

return null;

int count;

char[] chars = value.ToCharArray();

count = chars.Length;

if (count > 6)

{

succeeded = false;

return null;

}

if (count == 6 && chars[0] != '-')

{

succeeded = false;

return null;

}

for (int i = 0; i < count; i++)

{

succeeded = char.IsNumber(chars[i]) || (chars[i] == '-' && i == 0);

if (!succeeded)

return null;

}

if (chars[0] == '-')

{

if (count == 6)

{

succeeded = char.GetNumericValue(chars[1]) <= 3 &&

char.GetNumericValue(chars[2]) <= 2 &&

char.GetNumericValue(chars[3]) <= 7 &&

char.GetNumericValue(chars[4]) <= 6 &&

char.GetNumericValue(chars[5]) <= 8;

}

}

else

{

if (count == 5)

{

succeeded = char.GetNumericValue(chars[0]) <= 3 &&

char.GetNumericValue(chars[1]) <= 2 &&

char.GetNumericValue(chars[2]) <= 7 &&

char.GetNumericValue(chars[3]) <= 6 &&

char.GetNumericValue(chars[4]) <= 7;

}

}

if (succeeded)

return Int16.Parse(value);

return null;

}

#endregion

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: