//############################################################################// // RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION // PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS // AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO // UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO // RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS // CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS // OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON // COMPANY. // // THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S. GOVERNMENT // // UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY. // // WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE // EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED // BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION // 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION // 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER // OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER // LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS // BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT // APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL // PENALTIES. // // DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 : // FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R, // INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS // DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR // RECONSTRUCTION OF THE DOCUMENT. //############################################################################// using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.Serialization; namespace Raytheon.Units { /// /// This class represents a Pressure /// /// It has no constructors. Instead, it provides multiple methods for creating objects of this /// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. Pascal). /// /// Properties (e.g. Pascal) are provided to convert the value to other units and return /// as type double. /// [Serializable] [DataContract] public class Pressure { public enum Unit { Bar, Millibar, Pascal, PSI } public static IDictionary> UnitAbbreviations = new Dictionary>() { {Unit.Bar, new List(){ "bar" } }, {Unit.Millibar, new List(){ "mbar" } }, {Unit.Pascal, new List(){ "Pa" } }, {Unit.PSI, new List(){ "PSI" } }, }; private const Unit DefaultUnits = Unit.PSI; private const int PascalPerBar = 100000; private const double PascalPerPSI = 6894.75729; [DataMember(Name = "Pascal", IsRequired = true)] private double _pressure; // Pascal // map: unit => abbreviation, conversion method and property private static IDictionary> _unitInfo = new Dictionary>() { { Unit.Bar, new UnitInfo(UnitAbbreviations[Unit.Bar], FromBar, typeof(Pressure).GetProperty("Bar").GetGetMethod()) }, { Unit.Millibar, new UnitInfo(UnitAbbreviations[Unit.Millibar], FromMillibar, typeof(Pressure).GetProperty("Millibar").GetGetMethod()) }, { Unit.Pascal, new UnitInfo(UnitAbbreviations[Unit.Pascal], FromPascal, typeof(Pressure).GetProperty("Pascal").GetGetMethod()) }, { Unit.PSI, new UnitInfo(UnitAbbreviations[Unit.PSI], FromPSI, typeof(Pressure).GetProperty("PSI").GetGetMethod()) } }; /// /// Prevents a default instance of the class from being created /// Use FromXXX methods to create objects of this type. /// private Pressure() { throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object"); } /// /// ctor used by this class to create objects in FromXXX methods. /// /// The pressure - pascal private Pressure(double pressure) { this._pressure = pressure; } #region conversion properties public double Bar { get { return _pressure / PascalPerBar; } } public double Millibar { get { return _pressure / PascalPerBar * 1000; } } public double Pascal { get { return _pressure; } } public double PSI { get { return _pressure / PascalPerPSI; } } #endregion #region Creation Methods public static Pressure FromBar(double bars) { return new Pressure(bars * PascalPerBar); } public static Pressure FromMillibar(double millibars) { return new Pressure(millibars * PascalPerBar / 1000); } /// /// Returns Pressure object interpreting passed value as Pascal /// /// Pascal /// public static Pressure FromPascal(double pascal) { return new Pressure(pascal); } public static Pressure FromPSI(double psi) { return new Pressure(psi * PascalPerPSI); } #endregion public override bool Equals(object obj) { Pressure pressure = obj as Pressure; return (pressure == null) ? false : (this._pressure == pressure._pressure); } public override int GetHashCode() { return _pressure.GetHashCode(); } #region Binary Operators // not implementing %, &, |, ^, <<, >> public static Pressure operator +(Pressure left, Pressure right) { if (null == left) { throw new ArgumentNullException("left", "Cannot add a null Pressure"); } if (null == right) { throw new ArgumentNullException("right", "Cannot add null Pressure"); } return new Pressure(left._pressure + right._pressure); } public static Pressure operator -(Pressure left, Pressure right) { if (null == left) { throw new ArgumentNullException("left", "Cannot add a null Pressure"); } if (null == right) { throw new ArgumentNullException("right", "Cannot add null Pressure"); } return new Pressure(left._pressure - right._pressure); } public static Pressure operator *(Pressure pressure, double scalar) { if (null == pressure) { throw new ArgumentNullException("pressure", "Cannot multiply a null Pressure"); } return new Pressure(pressure._pressure * scalar); } public static Pressure operator *(double scalar, Pressure pressure) { if (null == pressure) { throw new ArgumentNullException("pressure", "Cannot multiply a null Pressure"); } return new Pressure(scalar * pressure._pressure); } public static Pressure operator /(Pressure pressure, double scalar) { if (null == pressure) { throw new ArgumentNullException("pressure", "Cannot divide a null Pressure"); } if (0.0 == scalar) { throw new DivideByZeroException("Cannot divide Pressure by 0"); } return new Pressure(pressure._pressure / scalar); } #endregion #region comparison operators public static bool operator ==(Pressure left, Pressure right) { bool bReturn = false; if (object.ReferenceEquals(left, null)) { if (object.ReferenceEquals(right, null)) { //both are null, so we are == bReturn = true; } } else { if (!object.ReferenceEquals(left, null) && !object.ReferenceEquals(right, null)) { bReturn = left._pressure == right._pressure; } } return bReturn; } public static bool operator !=(Pressure left, Pressure right) { return !(left == right); } public static bool operator <(Pressure left, Pressure right) { if (null == left) { throw new ArgumentNullException("left", "Cannot compare null Pressure"); } if (null == right) { throw new ArgumentNullException("right", "Cannot compare null Pressure"); } return (left._pressure < right._pressure); } public static bool operator >(Pressure left, Pressure right) { if (null == left) { throw new ArgumentNullException("left", "Cannot compare null Pressure"); } if (null == right) { throw new ArgumentNullException("right", "Cannot compare null Pressure"); } return (left._pressure > right._pressure); } public static bool operator <=(Pressure left, Pressure right) { if (null == left) { throw new ArgumentNullException("left", "Cannot compare null Pressure"); } if (null == right) { throw new ArgumentNullException("right", "Cannot compare null Pressure"); } return (left._pressure <= right._pressure); } public static bool operator >=(Pressure left, Pressure right) { if (null == left) { throw new ArgumentNullException("left", "Cannot compare null Pressure"); } if (null == right) { throw new ArgumentNullException("right", "Cannot compare null Pressure"); } return (left._pressure >= right._pressure); } #endregion #region parsing public static Pressure Parse(string s) { return Common.Parse(s, _unitInfo); } public static bool TryParse(string s, out Pressure value) { try { value = Pressure.Parse(s); return true; } catch (Exception) { value = null; return false; } } #endregion /// /// Returns a string appended with default units (e.g. "1.23 m/sec^2"). /// /// /// A string that represents this instance /// public override string ToString() { return ToString(DefaultUnits); } /// /// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2"). /// /// /// public string ToString(Unit units) { double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null); return $"{value} {_unitInfo[units].Abbreviation[0]}"; } } }