15

.NET には単位変換クラスがありますか? インチをミリメートルに、またはその逆に変換する必要があります。

4

7 に答える 7

14

私は以前にこの問題を扱ったことがあります。距離のために2つのクラスを作ることをお勧めします。1 つはインペリアル メジャーを持ち、もう 1 つはメトリック メジャーを持ちます。次に、それらの間を簡単に変換できますが、変換すると精度が失われるという明らかな注意事項があります。

以下は、測定の基本単位としてインチを使用したインペリアル距離クラスの例です。

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());
}

この単純な戦略を、重量、温度、液体測定などに使用できます。

于 2012-11-08T15:17:01.060 に答える
13

いいえ、組み込みのようなものはありません。ただし、単純に 25.4 で乗算または除算できます。

于 2011-05-17T07:39:05.430 に答える
3

.NET Framework にはこのようなものはありませんが、F# にはUnits of Measureがあります。

于 2011-05-17T07:47:41.840 に答える
2

いいえ、次のように自分で作成する必要があります。

public class Length
{
    private const double MillimetersPerInch = 25.4;
    private double _Millimeters;

    public static Length FromMillimeters(double mm)
    {
         return new Length { _Millimeters = mm };
    }

    public static Length FromInch(double inch)
    {
         return new Length { _Millimeters = inch * MillimetersPerInch };
    }

    public double Inch { get { return _Millimeters / MillimetersPerInch; } } 
    public double Millimeters { get { return _Millimeters; } }
}
于 2011-05-17T07:41:07.340 に答える
2

Csunits は、C# 用の優れた測定単位ライブラリです。 https://github.com/cureos/csunitsを参照してください。現在は放射線治療を対象としていますが、独自の単位と量を簡単に追加できます。

于 2011-05-17T08:26:08.043 に答える
2

No, there is no such unit conversions built into the framework. Should be easy enough to implement yourself, though.

于 2011-05-17T07:37:32.977 に答える