内容目录
||其代码如下:
/// <summary>
/// 值类型和字符串互转
/// </summary>
public class JsonStringToNumberConverter : JsonConverterFactory
{
/// <summary>
/// 获取默认实例
/// </summary>
public static JsonStringToNumberConverter Default { get; } = new JsonStringToNumberConverter();
/// <summary>
/// 返回类型是否可以转换
/// </summary>
/// <param name="typeToConvert"></param>
/// <returns></returns>
public override bool CanConvert(Type typeToConvert)
{
var typeCode = Type.GetTypeCode(typeToConvert);
return typeCode == TypeCode.Int32 ||
typeCode == TypeCode.Decimal ||
typeCode == TypeCode.Double ||
typeCode == TypeCode.Single ||
typeCode == TypeCode.Int64 ||
typeCode == TypeCode.Int16 ||
typeCode == TypeCode.Byte ||
typeCode == TypeCode.UInt32 ||
typeCode == TypeCode.UInt64 ||
typeCode == TypeCode.UInt16 ||
typeCode == TypeCode.SByte;
}
/// <summary>
/// 创建转换器
/// </summary>
/// <param name="typeToConvert"></param>
/// <param name="options"></param>
/// <returns></returns>
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var type = typeof(StringNumberConverter<>).MakeGenericType(typeToConvert);
var converter = Activator.CreateInstance(type);
if (converter == null)
{
throw new InvalidOperationException($"无法创建 {type.Name} 类型的转换器");
}
return (JsonConverter)converter;
}
/// <summary>
/// 文本表示的数值转换器
/// </summary>
/// <typeparam name="T"></typeparam>
private class StringNumberConverter<T> : JsonConverter<T>
{
private static readonly TypeCode typeCode = Type.GetTypeCode(typeof(T));
/// <summary>
/// 读取
/// </summary>
/// <param name="reader"></param>
/// <param name="typeToConvert"></param>
/// <param name="options"></param>
/// <returns></returns>
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.Number:
if (typeCode == TypeCode.Int32)
{
if (reader.TryGetInt32(out var value))
{
return Unsafe.As<int, T>(ref value);
}
}
if (typeCode == TypeCode.Int64)
{
if (reader.TryGetInt64(out var value))
{
return Unsafe.As<long, T>(ref value);
}
}
if (typeCode == TypeCode.Decimal)
{
if (reader.TryGetDecimal(out var value))
{
return Unsafe.As<decimal, T>(ref value);
}
}
if (typeCode == TypeCode.Double)
{
if (reader.TryGetDouble(out var value))
{
return Unsafe.As<double, T>(ref value);
}
}
if (typeCode == TypeCode.Single)
{
if (reader.TryGetSingle(out var value))
{
return Unsafe.As<float, T>(ref value);
}
}
if (typeCode == TypeCode.Byte)
{
if (reader.TryGetByte(out var value))
{
return Unsafe.As<byte, T>(ref value);
}
}
if (typeCode == TypeCode.SByte)
{
if (reader.TryGetSByte(out var value))
{
return Unsafe.As<sbyte, T>(ref value);
}
}
if (typeCode == TypeCode.Int16)
{
if (reader.TryGetInt16(out var value))
{
return Unsafe.As<short, T>(ref value);
}
}
if (typeCode == TypeCode.UInt16)
{
if (reader.TryGetUInt16(out var value))
{
return Unsafe.As<ushort, T>(ref value);
}
}
if (typeCode == TypeCode.UInt32)
{
if (reader.TryGetUInt32(out var value))
{
return Unsafe.As<uint, T>(ref value);
}
}
if (typeCode == TypeCode.UInt64)
{
if (reader.TryGetUInt64(out var value))
{
return Unsafe.As<ulong, T>(ref value);
}
}
break;
case JsonTokenType.String:
IConvertible str = reader.GetString() ?? "";
return (T)str.ToType(typeof(T), null);
}
throw new NotSupportedException($"无法将{reader.TokenType}转换为{typeToConvert}");
}
/// <summary>
/// 写入
/// </summary>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="options"></param>
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
switch (typeCode)
{
case TypeCode.Int32:
writer.WriteNumberValue(Unsafe.As<T, int>(ref value));
break;
case TypeCode.UInt32:
writer.WriteNumberValue(Unsafe.As<T, uint>(ref value));
break;
case TypeCode.Decimal:
writer.WriteNumberValue(Unsafe.As<T, decimal>(ref value));
break;
case TypeCode.Double:
writer.WriteNumberValue(Unsafe.As<T, double>(ref value));
break;
case TypeCode.Single:
writer.WriteNumberValue(Unsafe.As<T, uint>(ref value));
break;
case TypeCode.UInt64:
writer.WriteNumberValue(Unsafe.As<T, ulong>(ref value));
break;
case TypeCode.Int64:
writer.WriteNumberValue(Unsafe.As<T, long>(ref value));
break;
case TypeCode.Int16:
writer.WriteNumberValue(Unsafe.As<T, short>(ref value));
break;
case TypeCode.UInt16:
writer.WriteNumberValue(Unsafe.As<T, ushort>(ref value));
break;
case TypeCode.Byte:
writer.WriteNumberValue(Unsafe.As<T, byte>(ref value));
break;
case TypeCode.SByte:
writer.WriteNumberValue(Unsafe.As<T, sbyte>(ref value));
break;
default:
throw new NotSupportedException($"不支持非数字类型{typeof(T)}");
}
}
}
}
文章评论
可以使用 TypeDescriptor、TypeConverter 来做
return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(obj.ToString());