距离(英尺,英寸)类或结构

时间:2010-03-01 17:44:03

标签: c# .net

是否有人知道任何示例或代码显示可用于距离的类或结构,如DateTime结构?我需要能够以英尺和英寸为单位添加,减去和显示数据,并且使用转换方法会变得混乱。一个类或结构将是完美的,但我在搜索中没有发现任何东西。

4 个答案:

答案 0 :(得分:12)

使用结构,但使其不可变(所有属性都是get-only)。

属性至少应包括:

  • TotalFeet
  • TotalInches

方法至少应包括:

  • FromFeet(静态)
  • FromInches(静态)

将私人支持字段声明为:

private readonly double _meters;

编辑:也许是这样的。

public struct Distance : IEquatable<Distance>, IComparable<Distance>
{
    private static readonly double MetersPerKilometer = 1000.0;
    private static readonly double CentimetersPerMeter = 100.0;
    private static readonly double CentimetersPerInch = 2.54;
    private static readonly double InchesPerFoot = 12.0;
    private static readonly double FeetPerYard = 3.0;
    private static readonly double FeetPerMeter = CentimetersPerMeter / (CentimetersPerInch * InchesPerFoot);
    private static readonly double InchesPerMeter = CentimetersPerMeter / CentimetersPerInch;

    private readonly double _meters;

    public Distance(double meters)
    {
        this._meters = meters;
    }

    public double TotalKilometers
    {
        get
        {
            return _meters / MetersPerKilometer;
        }
    }

    public double TotalMeters
    {
        get
        {
            return _meters;
        }
    }

    public double TotalCentimeters
    {
        get
        {
            return _meters * CentimetersPerMeter;
        }
    }

    public double TotalYards
    {
        get
        {
            return _meters * FeetPerMeter / FeetPerYard;
        }
    }

    public double TotalFeet
    {
        get
        {
            return _meters * FeetPerMeter;
        }
    }

    public double TotalInches
    {
        get
        {
            return _meters * InchesPerMeter;
        }
    }

    public static Distance FromKilometers(double value)
    {
        return new Distance(value * MetersPerKilometer);
    }

    public static Distance FromMeters(double value)
    {
        return new Distance(value);
    }

    public static Distance FromCentimeters(double value)
    {
        return new Distance(value / CentimetersPerMeter);
    }

    public static Distance FromYards(double value)
    {
        return new Distance(value * FeetPerYard / FeetPerMeter);
    }

    public static Distance FromFeet(double value)
    {
        return new Distance(value / FeetPerMeter);
    }

    public static Distance FromInches(double value)
    {
        return new Distance(value / InchesPerMeter);
    }

    public static Distance operator +(Distance a, Distance b)
    {
        return new Distance(a._meters + b._meters);
    }

    public static Distance operator -(Distance a, Distance b)
    {
        return new Distance(a._meters - b._meters);
    }

    public static Distance operator -(Distance a)
    {
        return new Distance(-a._meters);
    }

    public override bool Equals(object obj)
    {
        if (!(obj is Distance))
            return false;

        return Equals((Distance)obj);
    }

    public bool Equals(Distance other)
    {
        return this._meters == other._meters;
    }

    public int CompareTo(Distance other)
    {
        return this._meters.CompareTo(other._meters);
    }

    public override int GetHashCode()
    {
        return _meters.GetHashCode();
    }

    public override string ToString()
    {
        return string.Format("{0}[m]", TotalMeters);
    }
}

答案 1 :(得分:8)

之前我已经编写了自包含的单元转换器类,但我不知道.NET公用的好。

话虽如此,写起来也很容易 - 只需制作一个可以从英寸或英尺构建的结构,并可转换为两者。

public struct Distance
{
     private Distance(int inches)
     {
         this.totalInches = inches;
     }

     private int totalInches;

     public int Inches { get { return this.totalInches % 12; }  }

     public int Feet { get { return this.totalInches / 12; } }

     public static Distance FromInches(int inches)
     {
          return new Distance(inches);
     }

     public static Distance FromFeet(int feet)
     {
          return new Distance(feet * 12);
     }

     public static Distance FromFeetAndInches(int feet, int inches)
     {
          return new Distance(feet * 12 + inches);
     }

}

答案 2 :(得分:0)

public class Length
{
    public double Inches { get; set; }

    public double Feet
    {
        get { return Inches / 12.0; }
        set { Inches = value * 12.0; }
    }

    public double Meters
    {
        get { return Inches / 39.3700787; }
        set { Inches = value * 39.3700787; }
    }

    public double Furlongs
    {
        get { return Feet / 660.0; }
        set { Feet = value * 660.0; }
    }

    public double Miles
    {
        get { return Furlongs / 8.0; }
        set { Furlongs = value * 8.0; }
    }
}

答案 3 :(得分:0)

我建议为距离制作两个班级。一个具有帝国措施,一个具有度量衡量标准。然后,您可以轻松地在它们之间来回转换,明显的警告是,当您这样做时会失去精确度。

这是一个英制距离等级的例子,以英寸为基本测量单位。

    public class ImperialDistance {

    public static readonly ImperialDistance Inch = new ImperialDistance(1.0);
    public static readonly ImperialDistance Foot = new ImperialDistance(12.0);
    public static readonly ImperialDistance Yard = new ImperialDistance(36.0);
    public static readonly ImperialDistance Mile = new ImperialDistance(63360.0);

    private double _inches;

    public ImperialDistance(double inches) {
        _inches = inches;
    }

    public double ToInches() {
        return _inches;
    }

    public double ToFeet() {
        return _inches / Foot._inches;
    }

    public double ToYards() {
        return _inches / Yard._inches;
    }

    public double ToMiles() {
        return _inches / Mile._inches;
    }

    public MetricDistance ToMetricDistance() {
        return new MetricDistance(_inches * 0.0254);
    }

    public override int GetHashCode() {
        return _inches.GetHashCode();
    }

    public override bool Equals(object obj) {
        var o = obj as ImperialDistance;
        if (o == null) return false;
        return _inches.Equals(o._inches);
    }

    public static bool operator ==(ImperialDistance a, ImperialDistance b) {
        // If both are null, or both are same instance, return true
        if (ReferenceEquals(a, b)) return true;

        // if either one or the other are null, return false
        if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) return false;

        // compare
        return a._inches == b._inches;
    }

    public static bool operator !=(ImperialDistance a, ImperialDistance b) {
        return !(a == b);
    }

    public static ImperialDistance operator +(ImperialDistance a, ImperialDistance b) {
        if (a == null) throw new ArgumentNullException();
        if (b == null) throw new ArgumentNullException();
        return new ImperialDistance(a._inches + b._inches);
    }

    public static ImperialDistance operator -(ImperialDistance a, ImperialDistance b) {
        if (a == null) throw new ArgumentNullException();
        if (b == null) throw new ArgumentNullException();
        return new ImperialDistance(a._inches - b._inches);
    }

    public static ImperialDistance operator *(ImperialDistance a, ImperialDistance b) {
        if (a == null) throw new ArgumentNullException();
        if (b == null) throw new ArgumentNullException();
        return new ImperialDistance(a._inches * b._inches);
    }

    public static ImperialDistance operator /(ImperialDistance a, ImperialDistance b) {
        if (a == null) throw new ArgumentNullException();
        if (b == null) throw new ArgumentNullException();
        return new ImperialDistance(a._inches / b._inches);
    }
}

这是一个以米为基本单位的公制等级:

public class MetricDistance {

    public static readonly MetricDistance Milimeter = new MetricDistance(0.001);
    public static readonly MetricDistance Centimeter = new MetricDistance(0.01);
    public static readonly MetricDistance Decimeter = new MetricDistance(0.1);
    public static readonly MetricDistance Meter = new MetricDistance(1.0);
    public static readonly MetricDistance Decameter = new MetricDistance(10.0);
    public static readonly MetricDistance Hectometer = new MetricDistance(100.0);
    public static readonly MetricDistance Kilometer = new MetricDistance(1000.0);

    private double _meters;

    public MetricDistance(double meters) {
        _meters = meters;
    }

    public double ToMilimeters() {
        return _meters / Milimeter._meters;
    }

    public double ToCentimeters() {
        return _meters / Centimeter._meters;
    }

    public double ToDecimeters() {
        return _meters / Decimeter._meters;
    }

    public double ToMeters() {
        return _meters;
    }

    public double ToDecameters() {
        return _meters / Decameter._meters;
    }

    public double ToHectometers() {
        return _meters / Hectometer._meters;
    }

    public double ToKilometers() {
        return _meters / Kilometer._meters;
    }

    public ImperialDistance ToImperialDistance() {
        return new ImperialDistance(_meters * 39.3701);
    }

    public override int GetHashCode() {
        return _meters.GetHashCode();
    }

    public override bool Equals(object obj) {
        var o = obj as MetricDistance;
        if (o == null) return false;
        return _meters.Equals(o._meters);
    }

    public static bool operator ==(MetricDistance a, MetricDistance b) {
        // If both are null, or both are same instance, return true
        if (ReferenceEquals(a, b)) return true;

        // if either one or the other are null, return false
        if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) return false;

        return a._meters == b._meters;
    }

    public static bool operator !=(MetricDistance a, MetricDistance b) {
        return !(a == b);
    }

    public static MetricDistance operator +(MetricDistance a, MetricDistance b) {
        if (a == null) throw new ArgumentNullException("a");
        if (b == null) throw new ArgumentNullException("b");
        return new MetricDistance(a._meters + b._meters);
    }

    public static MetricDistance operator -(MetricDistance a, MetricDistance b) {
        if (a == null) throw new ArgumentNullException("a");
        if (b == null) throw new ArgumentNullException("b");
        return new MetricDistance(a._meters - b._meters);
    }

    public static MetricDistance operator *(MetricDistance a, MetricDistance b) {
        if (a == null) throw new ArgumentNullException("a");
        if (b == null) throw new ArgumentNullException("b");
        return new MetricDistance(a._meters * b._meters);
    }

    public static MetricDistance operator /(MetricDistance a, MetricDistance b) {
        if (a == null) throw new ArgumentNullException("a");
        if (b == null) throw new ArgumentNullException("b");
        return new MetricDistance(a._meters / b._meters);
    }
}

这是一种测试方法,用于举例说明用法。

[TestMethod]
public void _5in_Equals_12_7cm() {
    var inches = new ImperialDistance(5);
    var cms = new MetricDistance(MetricDistance.Centimeter.ToMeters() * 12.7);
    var calcCentimeters = Math.Round(inches.ToMetricDistance().ToCentimeters(), 2, MidpointRounding.AwayFromZero);
    var calcInches = Math.Round(cms.ToImperialDistance().ToInches(), 2, MidpointRounding.AwayFromZero);

    Assert.AreEqual(cms.ToCentimeters(), 12.7);
    Assert.AreEqual(calcCentimeters, 12.7);
    Assert.AreEqual(inches.ToInches(), 5);
    Assert.AreEqual(calcInches, 5);
}

您还可以添加扩展方法

public static MetricDistance Centimeters(this Int32 that) {
    return new MetricDistance(MetricDistance.Centimeter.ToMeters() * that);
}

[TestMethod]
public void _100cm_plus_300cm_equals_400cm() {
    Assert.AreEqual(100.Centimeters() + 300.Centimeters(), 400.Centimeters());
}