它的实现原理则是借助反射,算是一个入门级的应用反射分(初、中、高)三部分入门级的应用自然是浅显的 但要解决字符串与基本类型的安全转换它足够用了
我们都知道在.NET的基本类型中具备一个安全字符串转换基本类型的方法即TryParse那么我们去反射去执行它而不需要写一个很难看的TryParse的函数体 这会造成一定的性能浪费但是可以接受的
实际上网上的很多人都说反射效率低但实际上反射的效率并有那么低下 如果反射执行一个方法做加减运算的函数一秒钟可以120~150W次左右 如果是常规写法则是7000~9000W左右 那么我们思考一下你需要一秒钟执行那么多次的方法?
不需要你可能执行1000次已经就很了不起 实际上你根本无法遭遇到这种情况 但是反射型的代码的确需要一定优化否则会大大降低性能这点的确是不否认的 当然如果你是通过InvokeMember反射执行成员 那么效率慢你可不能责怪反射本身 这本身则是代码优化问题 对于反射我们通常是尽可能避免InvokeMember方式,的确对于调用COM这样的确会很慢 因为本身Type::DefaultBinder已经实现过于复杂对各方面都进行了封装与考虑 那么如果考虑到反射调用COM优化的话你可以尝试自己编写一个专用于COM对象的Binder 当然这可能不可避免你需要去了解TLB类型库信息获取方面的文献 实际上你需要获取的信息都可以ITypeInfo2::GetDocument进行获取 它在内部是以一个memid方式存在
一个COM对象(System::_ComObject)全部是具象在IDispatch下而它必定会实现IDispatch::GetTypeInfo所以并不会存在无法获取COM类型库信息的问题
namespace STDLOGIC_SERVER.ValueType
{
using System;
using System.Globalization;
using System.Reflection;
/// <summary>
/// 用于对值类型数据的字符串与值类型数据相互格式化
/// </summary>
public static class ValueTypeFormatter
{
/// <summary>
/// 字符串到值类型,如 oct“1234”-> dec 668 is type int?
/// </summary>
/// <param name="type">值类型</typeparam>
/// <param name="value">欲被转换的字符串</param>
/// <param name="style">数值转换使用的方式(如HEX,BIN,OCT,DEC)</param>
/// <param name="provider">对特定数值转换使用“格式化提供商”</param>
/// <returns></returns>
public static object Parse(this string value, Type type, NumberStyles style = NumberStyles.None, IFormatProvider provider = null)
{
if (type == null)
{
return null;
}
if (type == typeof(string))
{
return value;
}
if (string.IsNullOrEmpty(value))
{
return null;
}
//
MethodInfo met = type.GetMethod("TryParse", new Type[] { typeof(string), typeof(NumberStyles), typeof(IFormatProvider), type.MakeByRefType() });
object[] args = null;
if (met == null)
{
met = type.GetMethod("TryParse", new Type[] { typeof(string), type.MakeByRefType() });
if (met == null)
{
return null;
}
args = new object[] { value, null };
}
else
{
args = new object[] { value, style, provider, null };
}
if (args == null)
{
return null;
}
if ((true).Equals(met.Invoke(null, args)))
{
return args[args.Length - 1];
}
return null;
}
/// <summary>
/// 字符串到值类型,如 oct“1234”-> dec 668 is type int?
/// </summary>
/// <typeparam name="T">值类型</typeparam>
/// <param name="value">欲被转换的字符串</param>
/// <param name="style">数值转换使用的方式(如HEX,BIN,OCT,DEC)</param>
/// <param name="provider">对特定数值转换使用“格式化提供商”</param>
/// <returns></returns>
public static T? Parse<T>(this string value, NumberStyles style = NumberStyles.None, IFormatProvider provider = null) where T : struct
{
object o = ValueTypeFormatter.Parse(value, typeof(T), style, provider);
if (o == null)
{
return null;
}
return (T)o;
}
/// <summary>
/// 将值类型数据转换成字符串
/// </summary>
/// <param name="value">值类型数据</param>
/// <returns></returns>
public static string To(this object value)
{
return Convert.ToString(value);
}
/// <summary>
/// 将值类型数据转换成字符串
/// </summary>
/// <typeparam name="T">值的类型</typeparam>
/// <param name="value">值类型数据</param>
/// <returns></returns>
public static string To<T>(this T value)
{
return Convert.ToString(value);
}
/// <summary>
/// 字符串到值类型,如 oct“1234”-> dec 668 is type int
/// </summary>
/// <returns></returns>
public static T TryParse<T>(this string value, NumberStyles style = NumberStyles.None, IFormatProvider provider = null) where T : struct
{
T? result = Parse<T>(value);
if (result == null)
{
return default(T);
}
return (T)result;
}
}
}