Sure, polymorphism. Anytime you see long switch statements or if/then/else constructs it's always possible to handle them using polymorphism and factories. In your case I'd imagine an ITemperatureConverter interface with concrete implementations for Fahrenheit, Celcius, Kelvin, and Rankine would do nicely.
UPDATE:
If you find you have this logic repeated, why not have a better abstraction for an Angle than a double?
If you're writing in an object-oriented language, it's a good idea to rise above primitives (e.g, double and, yes, string) to encapsulate behavior into objects.
I'd think about an Angle class that would hang onto the value and return it as whatever measure you wanted.
Here's one way to do it in Java. I'll leave the translation to C# and the rest for you.
package angles;
public class Angle
{
private double value;
private AngleUnit units;
public Angle()
{
this(0.0, AngleUnit.RADIANS);
}
public Angle(double value)
{
this(value, AngleUnit.RADIANS);
}
public Angle(double value, AngleUnit units)
{
this.value = value;
this.units = units;
}
public double getValue()
{
return value;
}
public AngleUnit getUnits()
{
return units;
}
public Angle convert(AngleUnit newUnits)
{
Angle newAngle = null;
if (this.units.equals(newUnits))
{
return this;
}
return newAngle;
}
}
package angles;
public interface AngleConverter
{
Angle convert(Angle angle, AngleUnit to);
}
package angles;
public enum AngleUnit
{
DEGREES, RADIANS, GRADIANS;
}
package angles;
import java.util.HashMap;
import java.util.Map;
public class DegreeConverter implements AngleConverter
{
private final Map<AngleUnit, Double> factors;
public DegreeConverter(Map<AngleUnit, Double> factors)
{
this.factors = new HashMap<AngleUnit, Double>();
this.factors.put(AngleUnit.DEGREES, 1.0);
this.factors.put(AngleUnit.RADIANS, Math.PI/180.0);
this.factors.put(AngleUnit.GRADIANS, 100.0/90.);
}
public Angle convert(Angle angle, AngleUnit to)
{
assert angle != null && to != null;
return new Angle(angle.getValue()*this.factors.get(to), to);
}
}