|
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace UnitsConversion
{
internal class Units : INotifyPropertyChanged
{
internal readonly Unit DegreesCelcius;
internal readonly Unit DegreesFahrenheit;
private Unit temperatureSystemUnit;
private IList<Unit> temperatureUnits;
private Unit temperatureUserUnit;
private Units()
{
TemperatureUnits = new[]
{
DegreesCelcius = new Unit("Degrees Celcius", "�C", 1.0, 0.0, UnitType.Temperature),
DegreesFahrenheit = new Unit("Degrees Fahrenheit", "�F", 1.8, 32, UnitType.Temperature)
};
// example
TemperatureSystemUnit = DegreesCelcius;
TemperatureUserUnit = DegreesFahrenheit;
}
public static Units Instance
{
get
{
return UnitsCreator.instance;
}
}
public Unit TemperatureSystemUnit
{
get { return temperatureSystemUnit; }
set
{
temperatureSystemUnit = value;
Changed("TemperatureSystemUnit");
}
}
public IList<Unit> TemperatureUnits
{
get { return temperatureUnits; }
set { temperatureUnits = value; }
}
public Unit TemperatureUserUnit
{
get { return temperatureUserUnit; }
set
{
temperatureUserUnit = value;
Changed("TemperatureUserUnit");
}
}
public event PropertyChangedEventHandler PropertyChanged;
internal void Changed(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
internal static double Convert(Unit from, Unit to, double value)
{
if (from.Type != to.Type)
throw new InvalidOperationException("Conversion between incompatible types.");
if (from.Shift == to.Shift && from.Scale == to.Scale)
return value;
double v = (value - from.Shift) / from.Scale;
return v * to.Scale + to.Shift;
}
internal double ConvertFromSystem(UnitType type, double value)
{
switch (type)
{
case UnitType.Temperature:
return Convert(TemperatureSystemUnit, TemperatureUserUnit, value);
default:
throw new InvalidOperationException("Unit type not supported.");
}
}
internal double ConvertToSystem(UnitType type, double value)
{
switch (type)
{
case UnitType.Temperature:
return Convert(TemperatureUserUnit, TemperatureSystemUnit, value);
default:
throw new InvalidOperationException("Unit type not supported.");
}
}
private class UnitsCreator
{
internal static readonly Units instance = new Units();
static UnitsCreator() { /* required */ }
}
internal struct Unit
{
internal string Abbreviation;
internal string Name;
internal double Scale;
internal double Shift;
internal UnitType Type;
public override string ToString()
{
return string.Format("{0} ({1})",
Name, Abbreviation);
}
internal Unit(string name, string abbreviation,
double scale, double shift, UnitType type)
{
if (scale == 0.0)
throw new ArgumentException("Scale factor cannot be zero.");
Name = name;
Abbreviation = abbreviation;
Scale = scale;
Shift = shift;
Type = type;
}
}
}
internal enum UnitType
{
Temperature,
Length
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I work primarily with the .NET technology stack, and specialize in accelerated code production via code generation (static or dynamic), aspect-oriented programming, MDA, domain-specific languages and anything else that gets products out the door faster. My languages of choice are C# and C++, though I'm open to suggestions.