简体   繁体   English

创建支持不同单位的温度等级(摄氏度,华氏度,开尔文度)

[英]Creating a Temperature class which supports different units (Celsius, Fahrenheit, Kelvin)

I'm working on a class to help me to convert between units, and I need to ask about the best way to create this work. 我正在上课,帮助我在单位之间进行转换,我需要询问创建这项工作的最佳方法。

This is my sample code about temperature: 这是关于温度的示例代码:

        public class Temperature
{
    private double _Celsius = 0;
    public double Celsius
    {
        get { return _Celsius; }
        set
        {
            _Fahrenheit = (value * 9 / 5) + 32;
            _Kelvin = value + 273.15;
        }
    }
    private double _Fahrenheit = 0;
    public double Fahrenheit
    {
        get { return _Fahrenheit; }
        set
        {
            _Celsius = (value - 32) * 5/9;
            _Kelvin = _Celsius + 273.15;
        }
    }
    private double _Kelvin = 0;
    public double Kelvin
    {
        get { return _Kelvin; }
        set
        {
            _Celsius = value - 273.15;
            _Fahrenheit = (_Celsius * 9 / 5) + 32;
        }
    }
}

I hope to know if there is another good one for this class or not? 我希望知道这个班级是否还有其他好的一个?

Why do you have three fields _Celsius , _Fahrenheit , _Kelvin when just one (say, _Celsius ) is enough: 为什么只有一个(比如说, _Celsius )就足够了,有三个字段_Celsius_Fahrenheit_Kelvin

  public class Temperature {
    private double _Celsius

    public double Celsius {
      get {
        return _Celsius;
      }
      set {
        // Simplest: no validation (e.g. -500 degree is an evident error)
        _Celsius = value;
      } 
    }

    public double Kelvin {
      get { 
        return Celsius + 273.15;
      }  
      set {
        Celsius = value - 273.15;
      } 
    }

    public double Fahrenheit {
      get { 
        return Celsius * 9 / 5 + 32;
      }  
      set {
        Celsius = (value - 32) * 5 / 9;
      } 
    }
  } 

Now let's think on what is the expected way of using your routine? 现在让我们考虑一下使用常规的预期方法是什么? Eg I want to convert 100 Fahrenheit to Kelvin : 例如,我想将100 华氏度转换为开尔文

  double result = new Temperature() { Fahrenheit = 100.0 }.Kelvin;

a bit wordy and counter-intuitive, right? 有点罗嗦和反直觉,对吧? May be a better choice is to implement a bunch of static method s? 可能更好的选择是实现一堆static method吗? And do not create any class at all? 并且根本不创建任何课程?

  public static class Temperatures {
    public static double FahrenheitToCelsius(double value) {...} 

    public static double CelsiusToKelvin(double value) {...}

    public static double FahrenheitToKelvin(double value) {
      return CelsiusToKelvin(FahrenheitToCelsius(value)); 
    }
    ...
  } 

  ...

  double result = Temperatures.FahrenheitToKelvin(100.0); 

A temperature is basically a type of "complex number." 温度基本上是一种“复数”。 It can be measured in different units of measurement, but ultimately you should still be able to compare two different temperatures to determine if they're equal, or if one is "greater than" the other. 它可以用不同的测量单位来衡量,但最终你仍然应该能够比较两个不同的温度,以确定它们是否相等,或者一个是否“大于”另一个。 You may also want to add two temperatures or subtract them. 您可能还想添加两个温度或减去它们。

I see this class behaving similarly to the .NET-provided TimeSpan class. 我看到这个类的行为类似于.NET提供的TimeSpan类。 Your Temperature class' implementation would choose a single unit of measurement to use privately - let's say Kelvin. 你的温度等级的实施将选择一个单独的测量单位私人使用 - 让我们说开尔文。 The Temperature then provides "convenience" properties, which provide the temperature in any of your desired units of measurement (Farenheit or Celsius): 温度然后提供“便利”属性,以任何您想要的测量单位(华氏度或摄氏度)提供温度:

public class Temperature
{
    private double _kelvin = 0.0;
    public double Kelvin
    { 
        get { return _kelvin; }
        set { _kelvin = value; }
    }

    public double Fahrenheit 
    {
        get { return /* convert Kelvin to Fahrenheit */; }
        set { _kelvin = /* convert Fahrenheit to Kelvin */; }
    }


    public double Celsius
    {
        get { return /* convert Kelvin to Celsius */; }
        set { _kelvin = /* convert Celsius to Kelvin */; }
    }
}

Additionally - like the TimeSpan class - you'll want static methods which allow you to quickly and easily create an instance of your Temperature, using whatever "base measurement" unit you prefer at the time: 此外 - 与TimeSpan类一样 - 您将需要静态方法,使您可以使用您当时喜欢的任何“基础测量”单元快速轻松地创建温度实例:

/* Also inside the Temperature class: */
public static Temperature FromKelvin(double kelvin)
{
    var temperature = new Temperature();
    temperature.Kelvin = kelvin;
    return temperature;
}

public static Temperature FromFahrenheit(double fahrenheit)
{
    var temperature = new Temperature();
    temperature.Fahrenheit = fahrenheit;
    return temperature;
}

public static Temperature FromCelsius(double celsius)
{
    var temperature = new Temperature();
    temperature.Celsius = celsius;
    return temperature;
}

Using this approach, you wind up with some nice clean usage syntax; 使用这种方法,您可以使用一些很好的干净使用语法;

var myTemperatureInKelvin = Temperature.FromCelsius(100.0).Kelvin;

Finally - to get some real use out of such a class - you would want to implement comparison and arithmetic operators for equality, greater-than and less-than comparisons, addition, subtraction, etc. This allows you to very cleanly compare or add multiple temperatures together; 最后 - 为了从这样的类中获得一些实际用途 - 你需要实现比较和算术运算符的相等性,大于和小于比较,加法,减法等。这使你可以非常干净地比较或添加多个温度在一起;

var resultInFahrenheit = (Temperature.FromCelsius(100.0) + Temperature.FromKelvin(200.0)).Fahrenheit;

Crazy! 疯! And useful! 而且很有用!

I'm guessing you probably don't want to have a load Temperature objects, you just want to convert one number to another one. 我猜你可能不想加载温度对象,你只想将一个数字转换为另一个数字。 So I would consider making Temperature a static class ie 所以我会考虑将温度设为静态类,即

public static Temperature

So you could write a method like 所以你可以写一个像这样的方法

public static double GetKelvinFromCelsius(double celsius) {
     return (celsius + 273.15);
}

Which could be used like: 可以使用如下:

double kelvinTemperature = Temperature.GetKelvinFromCelsius(400);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM