摘要
在现代软件开发中,准确处理不同单位的转换是一个常见而复杂的需求。无论是处理温度、长度、重量还是其他物理量,都需要可靠的单位转换机制。本文将深入介绍 Units.NET 库,展示如何在 .NET 应用中优雅地处理单位转换。
基础配置
首先,通过 NuGet 安装 Units.NET:
| <PackageReference Include="UnitsNet" Version="5.x.x" /> |
实战示例:天气 API
基础模型定义
| public record WeatherForecast( |
| Temperature Temperature, |
| DateTime Date, |
| string Summary |
| ); |
|
|
| public record WeatherResponse( |
| string DisplayValue, |
| DateTime Date, |
| string Summary |
| ); |
API 端点实现
| var summaries = new[] |
| { |
| "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" |
| }; |
|
|
| app.MapGet("/weather", (string? unit) => |
| { |
| var forecasts = Enumerable.Range(1, 5).Select(index => |
| { |
| |
| var tempC = Temperature.FromDegreesCelsius(Random.Shared.Next(-20, 55)); |
| |
| var temp = unit?.ToLowerInvariant() switch |
| { |
| "f" or "fahrenheit" => tempC.ToUnit(TemperatureUnit.DegreeFahrenheit), |
| "k" or "kelvin" => tempC.ToUnit(TemperatureUnit.Kelvin), |
| _ => tempC |
| }; |
|
|
| return new WeatherForecast( |
| Temperature: temp, |
| Date: DateTime.Now.AddDays(index), |
| Summary: summaries[Random.Shared.Next(summaries.Length)] |
| ); |
| }) |
| .ToArray(); |
|
|
| return forecasts.Select(f => new WeatherResponse( |
| Date: f.Date, |
| Summary: f.Summary, |
| DisplayValue: f.Temperature.ToString("F2") |
| )); |
| }) |
| .WithName("GetWeatherForecast"); |
当请求的units单位不同时,将输出相同温度的不同单位表示:
单位相互转换
| public static class UnitConverter |
| { |
| public static Temperature ConvertTemperature( |
| double value, |
| string fromUnit, |
| string toUnit) |
| { |
| var temperature = fromUnit.ToLowerInvariant() switch |
| { |
| "c" => Temperature.FromDegreesCelsius(value), |
| "f" => Temperature.FromDegreesFahrenheit(value), |
| "k" => Temperature.FromKelvins(value), |
| _ => throw new ArgumentException($"Unsupported unit: {fromUnit}") |
| }; |
|
|
| return toUnit.ToLowerInvariant() switch |
| { |
| "c" => temperature.ToUnit(TemperatureUnit.DegreeCelsius), |
| "f" => temperature.ToUnit(TemperatureUnit.DegreeFahrenheit), |
| "k" => temperature.ToUnit(TemperatureUnit.Kelvin), |
| _ => throw new ArgumentException($"Unsupported unit: {toUnit}") |
| }; |
| } |
| } |
数学运算支持
Units.NET 支持各种数学运算,使得单位计算变得简单:
| public class UnitCalculations |
| { |
| public static Speed CalculateSpeed(Length distance, Duration time) |
| { |
| return distance / time; |
| } |
|
|
| public static Acceleration CalculateAcceleration(Speed initialSpeed, Speed finalSpeed, Duration time) |
| { |
| return (finalSpeed - initialSpeed) / time; |
| } |
|
|
| public static Energy CalculateKineticEnergy(Mass mass, Speed velocity) |
| { |
| double massValue = mass.Kilograms; |
| double velocityValue = velocity.MetersPerSecond; |
| double energyValue = 0.5 * massValue * velocityValue * velocityValue; |
| return Energy.FromJoules(energyValue); |
| } |
| } |
|
|
| |
| var distance = Length.FromKilometers(100); |
| var time = Duration.FromHours(2); |
| var speed = UnitCalculations.CalculateSpeed(distance, time); |
| Console.WriteLine($"Speed: {speed.ToUnit(SpeedUnit.KilometerPerHour)}"); |
代码执行后,控制台将输出:Speed: 50 km/h
文化本地化支持
| var usEnglish = new CultureInfo("en-US"); |
| var russian = new CultureInfo("ru-RU"); |
| var oneKg = Mass.FromKilograms(1); |
| |
| |
| CultureInfo.CurrentCulture = russian; |
| string kgRu = oneKg.ToString(); |
|
|
| |
| string mgUs = oneKg.ToUnit(MassUnit.Milligram).ToString(usEnglish); |
| string mgRu = oneKg.ToUnit(MassUnit.Milligram).ToString(russian); |
|
|
| Console.WriteLine(mgUs); |
| Console.WriteLine(mgRu); |
| |
| Mass kg = Mass.Parse("1.0 kg", usEnglish); |
|
|
| |
| RotationalSpeedUnit rpm1 = RotationalSpeed.ParseUnit("rpm"); |
| RotationalSpeedUnit rpm2 = RotationalSpeed.ParseUnit("r/min"); |
|
|
| |
| string kgAbbreviation = Mass.GetAbbreviation(MassUnit.Kilogram); |
控制台将输出不同文化设置下的标准单位
结论
Units.NET 是一个强大而灵活的单位转换库,它不仅简化了单位转换的实现,还提供了丰富的功能支持。通过使用 Units.NET,开发者可以专注于业务逻辑,而不必担心单位转换的复杂性。无论是构建天气 API、物流系统还是科学计算应用,Units.NET 都是处理单位转换的理想选择。
转自https://www.cnblogs.com/madtom/p/18653522
该文章在 2025/1/7 15:42:57 编辑过