一、基础类型转换器
1.1 内置类型转换
// 使用Convert类进行基础类型转换
int intValue = Convert.ToInt32("123"); // 字符串转整型
double dblValue = Convert.ToDouble("3.14"); // 字符串转双精度
DateTime dateValue = Convert.ToDateTime("2025-08-01"); // 字符串转日期
![图片[1]_C#中Converter的深度应用指南_知途无界](https://zhituwujie.com/wp-content/uploads/2025/08/d2b5ca33bd20250826111917.png)
1.2 安全转换方法
// 使用TryParse避免转换异常
if (int.TryParse("456", out int safeInt)) {
Console.WriteLine($"安全转换结果: {safeInt}");
} else {
Console.WriteLine("转换失败");
}
二、自定义类型转换器
2.1 IConvertible接口实现
public class Product : IConvertible
{
public string Name { get; set; }
public decimal Price { get; set; }
public TypeCode GetTypeCode() => TypeCode.Object;
public decimal ToDecimal(IFormatProvider provider) => Price;
// 实现其他接口方法...
}
2.2 TypeConverter应用
[TypeConverter(typeof(ProductConverter))]
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
}
public class ProductConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
=> sourceType == typeof(string);
public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo culture, object value)
{
var parts = ((string)value).Split('|');
return new Product { Id = parts[0], Name = parts[1] };
}
}
// 使用示例
var converter = TypeDescriptor.GetConverter(typeof(Product));
var product = (Product)converter.ConvertFrom("P1001|笔记本电脑");
三、JSON序列化转换
3.1 JsonConverter应用
public class DecimalJsonConverter : JsonConverter<decimal>
{
public override decimal Read(ref Utf8JsonReader reader,
Type typeToConvert, JsonSerializerOptions options)
=> reader.GetDecimal();
public override void Write(Utf8JsonWriter writer,
decimal value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString("N2"));
}
// 注册使用
var options = new JsonSerializerOptions
{
Converters = { new DecimalJsonConverter() }
};
string json = JsonSerializer.Serialize(new { Amount = 1234.5678m }, options);
3.2 复杂对象转换
public class ProductJsonConverter : JsonConverter<Product>
{
public override Product Read(ref Utf8JsonReader reader,
Type typeToConvert, JsonSerializerOptions options)
{
using var jsonDoc = JsonDocument.ParseValue(ref reader);
var root = jsonDoc.RootElement;
return new Product {
Id = root.GetProperty("product_code").GetString(),
Name = root.GetProperty("product_name").GetString(),
Price = root.GetProperty("price").GetDecimal()
};
}
// Write方法实现...
}
四、LINQ查询转换
4.1 Select投影转换
var products = new List<Product>();
var productDtos = products.Select(p => new ProductDto
{
Id = p.Id,
DisplayName = $"{p.Name} (${p.Price})"
}).ToList();
4.2 自定义LINQ转换器
public static class LinqExtensions
{
public static IEnumerable<TResult> ConvertAll<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TResult> converter)
{
foreach (var item in source)
{
yield return converter(item);
}
}
}
// 使用示例
var discountedProducts = products.ConvertAll(p => new {
p.Name,
DiscountPrice = p.Price * 0.9m
});
五、数据库映射转换
5.1 Dapper类型处理器
public class ProductStatusHandler : SqlMapper.TypeHandler<ProductStatus>
{
public override ProductStatus Parse(object value)
=> ProductStatus.FromValue((int)value);
public override void SetValue(IDbDataParameter parameter, ProductStatus value)
{
parameter.Value = value.Value;
parameter.DbType = DbType.Int32;
}
}
// 注册处理器
SqlMapper.AddTypeHandler(new ProductStatusHandler());
5.2 EF Core值转换器
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property(p => p.Price)
.HasConversion(
v => v.ToString(),
v => decimal.Parse(v));
}
六、ASP.NET Core模型绑定
6.1 自定义模型绑定器
public class ProductModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var model = new Product();
model.Id = bindingContext.ValueProvider.GetValue("id").FirstValue;
model.Name = bindingContext.ValueProvider.GetValue("name").FirstValue;
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}
// 注册绑定器
services.AddControllers(options =>
{
options.ModelBinderProviders.Insert(0, new ProductModelBinderProvider());
});
6.2 格式化器转换
public class ProductInputFormatter : TextInputFormatter
{
public ProductInputFormatter()
{
SupportedMediaTypes.Add("text/product");
SupportedEncodings.Add(Encoding.UTF8);
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(
InputFormatterContext context, Encoding encoding)
{
using var reader = new StreamReader(context.HttpContext.Request.Body, encoding);
var content = await reader.ReadToEndAsync();
var parts = content.Split(';');
return InputFormatterResult.Success(new Product {
Id = parts[0],
Name = parts[1]
});
}
}
七、XAML绑定转换器
7.1 WPF值转换器
[ValueConversion(typeof(bool), typeof(Brush))]
public class BoolToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
return (bool)value ? Brushes.Green : Brushes.Red;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<!-- XAML中使用 -->
<Label Background="{Binding IsAvailable, Converter={StaticResource BoolToBrushConverter}}"/>
7.2 多值转换器
public class MultiValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType,
object parameter, CultureInfo culture)
{
return $"{values[0]} - {values[1]}";
}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
八、高级转换场景
8.1 表达式树转换
public static Expression<Func<TTarget, bool>> ConvertPredicate<TSource, TTarget>(
Expression<Func<TSource, bool>> sourcePredicate)
{
var parameter = Expression.Parameter(typeof(TTarget), "x");
var body = new PredicateRewriter(parameter).Visit(sourcePredicate.Body);
return Expression.Lambda<Func<TTarget, bool>>(body, parameter);
}
class PredicateRewriter : ExpressionVisitor
{
private readonly ParameterExpression _parameter;
public PredicateRewriter(ParameterExpression parameter)
{
_parameter = parameter;
}
protected override Expression VisitMember(MemberExpression node)
{
// 实现属性映射逻辑
return Expression.Property(_parameter, node.Member.Name);
}
}
8.2 动态类型转换
public static dynamic ConvertToDynamic(object obj)
{
var expando = new ExpandoObject();
var dict = (IDictionary<string, object>)expando;
foreach (var prop in obj.GetType().GetProperties())
{
dict[prop.Name] = prop.GetValue(obj);
}
return expando;
}
九、性能优化技巧
9.1 转换缓存策略
public static class ConverterCache<TInput, TOutput>
{
private static readonly ConcurrentDictionary<TInput, TOutput> _cache
= new ConcurrentDictionary<TInput, TOutput>();
public static TOutput Convert(TInput input, Func<TInput, TOutput> converter)
=> _cache.GetOrAdd(input, converter);
}
9.2 委托缓存
public static class Converter<TInput, TOutput>
{
private static Func<TInput, TOutput> _converter;
public static TOutput FastConvert(TInput input)
{
if (_converter == null)
{
var param = Expression.Parameter(typeof(TInput));
var convertMethod = typeof(Convert).GetMethod("ChangeType",
new[] { typeof(object), typeof(Type) });
var body = Expression.Convert(param, typeof(TOutput));
_converter = Expression.Lambda<Func<TInput, TOutput>>(body, param).Compile();
}
return _converter(input);
}
}
十、最佳实践总结
10.1 转换器选择矩阵
| 场景 | 推荐方案 | 性能考量 |
|---|---|---|
| 简单类型转换 | Convert类/TryParse | 最高效 |
| 复杂对象映射 | 自定义TypeConverter | 中等,适合设计时 |
| JSON/XML序列化 | JsonConverter | 需考虑序列化开销 |
| 数据库交互 | Dapper/EF Core转换器 | 中等,批处理优化 |
| UI数据绑定 | IValueConverter | 低频率触发 |
10.2 异常处理规范
public TOutput SafeConvert<TInput, TOutput>(TInput input)
{
try
{
var converter = TypeDescriptor.GetConverter(typeof(TOutput));
if (converter.CanConvertFrom(typeof(TInput)))
{
return (TOutput)converter.ConvertFrom(input);
}
throw new InvalidOperationException("不支持的转换类型");
}
catch (FormatException ex)
{
// 记录日志并返回默认值
return default;
}
catch (NotSupportedException ex)
{
// 尝试其他转换方案
return FallbackConvert(input);
}
}
核心建议:
- 优先使用框架内置转换机制(如System.Convert)
- 复杂场景采用TypeConverter实现设计时支持
- JSON序列化自定义需考虑跨平台兼容性
- 高频转换操作应使用表达式树或委托缓存
- 始终为转换操作添加适当的异常处理
性能关键点:
- 避免在循环中重复创建转换器实例
- 对频繁使用的转换结果实施缓存
- 考虑使用Span处理内存密集型转换
- 异步IO操作时使用ValueTask减少分配
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END
























暂无评论内容