Microsoft loves using temperature in .NET examples. See here and here.
So, I decided to combine them all into a nice structure that implements IFormattable
, IComparable
, IEquatable
<t>, etc. That way, they don't have to keep rewriting it themselves.
The code also gives some good examples on operator overloading. Have fun.
using System;
using System.Globalization;
public enum TemperatureUnit
{
Kelvin,
Celsius,
Fahrenheit
}
public struct Temperature : IFormattable, IComparable,
IComparable<Temperature>, IEquatable<Temperature>
{
private double _Kelvin;
public Temperature(double kelvin) : this() { _Kelvin = kelvin; }
public Temperature(double temperature, TemperatureUnit unit)
: this()
{
switch (unit)
{
case TemperatureUnit.Kelvin:
_Kelvin = temperature;
break;
case TemperatureUnit.Celsius:
Celsius = temperature;
break;
case TemperatureUnit.Fahrenheit:
Fahrenheit = temperature;
break;
default:
throw new ArgumentException(
"The temperature unit '" + unit.ToString() + "' is unknown.");
}
}
public double Kelvin
{
get { return _Kelvin; }
set { _Kelvin = value; }
}
public double Celsius
{
get { return KelvinToCelsius(_Kelvin); }
set { _Kelvin = CelsiusToKelvin(value); }
}
public double Fahrenheit
{
get { return KelvinToFahrenheit(_Kelvin); }
set { _Kelvin = FahrenheitToKelvin(value); }
}
public double ValueIn(TemperatureUnit unit)
{
switch (unit)
{
case TemperatureUnit.Kelvin: return _Kelvin;
case TemperatureUnit.Celsius: return Celsius;
case TemperatureUnit.Fahrenheit: return Fahrenheit;
default: throw new ArgumentException(
"Unknown temperature unit '" + unit.ToString() + "'.");
}
}
public string ToString(string format, IFormatProvider provider)
{
if (String.IsNullOrEmpty(format)) format = "G";
if (provider == null) provider = CultureInfo.CurrentCulture;
switch (format.ToUpperInvariant())
{
case "G":
case "C":
return Celsius.ToString("F2", provider) + " °C";
case "F":
return Fahrenheit.ToString("F2", provider) + " °F";
case "K":
return _Kelvin.ToString("F2", provider) + " K";
default:
throw new FormatException(
String.Format("The {0} format string is not supported.", format));
}
}
public string ToString(string format)
{
return ToString(format, null);
}
public override string ToString()
{
return ToString(null, null);
}
public string ToString(TemperatureUnit unit, IFormatProvider provider)
{
switch (unit)
{
case TemperatureUnit.Celsius:
return ToString("C", provider);
case TemperatureUnit.Fahrenheit:
return ToString("F", provider);
case TemperatureUnit.Kelvin:
return ToString("K", provider);
default:
throw new FormatException("The temperature unit '" +
unit.ToString() + "' is unknown.");
}
}
public string ToString(TemperatureUnit unit)
{
return ToString(unit, null);
}
public int CompareTo(Temperature value)
{
return _Kelvin.CompareTo(value._Kelvin);
}
public int CompareTo(object value)
{
if (value == null) return 1;
if (!(value is Temperature)) throw new ArgumentException();
return CompareTo((Temperature)value);
}
public bool Equals(Temperature value)
{
return _Kelvin == value._Kelvin;
}
public override bool Equals(object value)
{
if (value == null) return false;
if (!(value is Temperature)) return false;
return Equals((Temperature)value);
}
public override int GetHashCode()
{
return _Kelvin.GetHashCode();
}
public static bool operator ==(Temperature t1, Temperature t2)
{
return t1.Equals(t2);
}
public static bool operator !=(Temperature t1, Temperature t2)
{
return !t1.Equals(t2);
}
public static bool operator >(Temperature t1, Temperature t2)
{
return t1._Kelvin > t2._Kelvin;
}
public static bool operator <(Temperature t1, Temperature t2)
{
return t1._Kelvin < t2._Kelvin;
}
public static bool operator >=(Temperature t1, Temperature t2)
{
return t1._Kelvin >= t2._Kelvin;
}
public static bool operator <=(Temperature t1, Temperature t2)
{
return t1._Kelvin <= t2._Kelvin;
}
public static Temperature operator +(Temperature t1, Temperature t2)
{
return new Temperature(t1._Kelvin + t2._Kelvin);
}
public static Temperature operator -(Temperature t1, Temperature t2)
{
return new Temperature(t1._Kelvin - t2._Kelvin);
}
public static Temperature operator *(Temperature t1, Temperature t2)
{
return new Temperature(t1._Kelvin * t2._Kelvin);
}
public static Temperature operator /(Temperature t1, Temperature t2)
{
return new Temperature(t1._Kelvin / t2._Kelvin);
}
public static Temperature operator %(Temperature t1, Temperature t2)
{
return new Temperature(t1._Kelvin % t2._Kelvin);
}
public static double KelvinToCelsius(double kelvin)
{
return kelvin - 273.15;
}
public static double CelsiusToKelvin(double celsius)
{
return celsius + 273.15;
}
public static double KelvinToFahrenheit(double kelvin)
{
return kelvin * 9 / 5 - 459.67;
}
public static double FahrenheitToKelvin(double fahrenheit)
{
return (fahrenheit + 459.67) * 5 / 9;
}
public static double FahrenheitToCelsius(double fahrenheit)
{
return (fahrenheit - 32) * 5 / 9;
}
public static double CelsiusToFahrenheit(double celsius)
{
return celsius * 9 / 5 + 32;
}
}