lenguaje - operador ? c#
¿Alternativa a escribir muchas declaraciones if? (5)
¿Hay alguna manera de que puedas escribir una instrucción switch
lugar?
switch (something)
{
case "degrees" : do work
...etc
}
Aquí está mi método:
private void ConvertValues()
{
txtResult.Text = angles[cmbUnits1.SelectedIndex];
double value1 = Convert.ToDouble(txtValue1.Text);
double value2 = Convert.ToDouble(txtValue2.Text);
int unit1 = cmbUnits1.SelectedIndex;
}
Lo que quiero que el método haga es seleccionar los ComboBoxes y probar los valores. Pero quiero saber si hay una alternativa a esto:
if( angles[cmbUnits1.SelectedIndex].Equals("Degrees") &&
angles[cmbUnits2.SelectedIndex].Equals("Radians")) {
...
}
Por cierto, estoy creando una especie de convertidor unitario, así que tendré secciones distintas a los ángulos. Así que me gustaría alguna enumeración, interfaz, clase abstracta o clase que pueda implementar. ¿Tal vez una clase con el nombre de Unidad? De modo que puedo crear nuevos objetos como Unit degrees = new Unit(Units.Angle)
con unidades como una enumeración. O simplemente Unit sqrMillimeters = new Unit("Area");
?
¿Qué tal una combinación de SelectedIndexChanged / SelectedValueChanged Events y algún polimorfismo?
Puede concatenar ambas cadenas ("GradosRadios") y llamar a un Método llamado "GradosRadios" a través de Reflexión:
MethodInfo theMethod = thisType.GetMethod(methodName);
theMethod.Invoke(this, parameters);
Donde methodName son las cadenas concatenadas (tal vez con información adicional, como "convertir" + unidad1 + "2" + unidad2, como "convertDegrees2Radians"), y los parámetros es una matriz que contiene ambos valores.
double UnitToFactor(string unit) { returns 1 for radians, pi/180 for degrees, etc }
entonces
ratio = UnitToFactor(unit1) / UnitToFactor(unit2);
y dest = src*ratio
De esta manera, en lugar de declaraciones N ^ 2 if (), solo tienes N.
Claro, polimorfismo. Cada vez que vea instrucciones de conmutación largas o construcciones de / then / else, siempre será posible manejarlas usando polimorfismo y fábricas. En su caso, me imagino que una interfaz ITemperatureConverter con implementaciones concretas para Fahrenheit, Celcius, Kelvin y Rankine sería muy útil.
ACTUALIZAR:
Si encuentra que tiene esta lógica repetida, ¿por qué no tener una mejor abstracción para un ángulo que un doble?
Si escribe en un lenguaje orientado a objetos, es una buena idea superar las primitivas (por ejemplo, doble y sí, cadena) para encapsular el comportamiento en objetos.
Pensaría en una clase Angle que se aferraría al valor y lo devolvería como quisiera.
Esta es una forma de hacerlo en Java. Dejaré la traducción a C # y el resto para ti.
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);
}
}