2017-01-20 1 views
1

Nous sommes en train d'écrire une application de conversion de données.UnitsNet - Quelle est la meilleure façon de faire la conversion d'unité d'exécution

Nous avons 10s de 1000s d'équations qui doivent être extraites dans un modèle appelé «modèle».

Le modèle prendra l'unité de mesure la plus courante pour un ensemble donné d'équations.

Ensuite, la valeur de chaque équation doit être ajustée pour s'assurer que sa valeur correspond à l'unité de mesure sur le modèle. Donc, je cherche à utiliser UnitsNet pour convertir les valeurs de variables, étant donné une variable source et son unité, en une unité cible. Le problème que j'ai, c'est que nous ne savons pas au moment de la compilation ni ce qu'est l'unité source, ni l'unité cible. Tout ce que nous avons, c'est l'abréviation de la chaîne d'unités source et cible dans l'équation qui arrive à l'exécution (et certaines d'entre elles seront des unités personnalisées).

Exemple simple:

Unité cible: mA (milliampères) équation Source: Is = 8A (Ampères)

Nous devons être en mesure de reconnaître l'unité de mesure de l'abréviation, le comparer à une unité cible, puis ajuster la valeur en conséquence:

dans le cas ci-dessus, nous multiplions 8 ampères par 1000 pour égaler 8000 milliampères.

Je ne vois pas de façon succincte de le faire avec UnitsNet.

Quelque chose brut comme celui-ci est tout ce que je jusqu'à présent (ce qui est un test unitaire écrit en xUnit):

[Theory] 
[InlineData("A", "mA", "8")] 
public void DoConversion(string sourceUnit, string targetUnit, string variableValue) 
{ 
    double result = 0; 
    ElectricCurrent sourceCurrent; 
    if (ElectricCurrent.TryParse($"{variableValue}{sourceUnit}", out sourceCurrent)) 
    { 
     ElectricCurrent targetCurrent; 
     if (ElectricCurrent.TryParse($"1{targetUnit}", out targetCurrent)) 
     { 
      var electricCurrentUnit = GetElectricCurrentUnitFromAbbreviation(targetUnit); 
      if (electricCurrentUnit == ElectricCurrentUnit.Ampere) 
      { 
       result = sourceCurrent.Amperes; 
      } 
      if (electricCurrentUnit == ElectricCurrentUnit.Milliampere) 
      { 
       result = sourceCurrent.Milliamperes; 
      } 
     } 
    } 
    result.Should().Be(8000); 

    // TODO: Add every other combination of all possible Units and their Scales- OMG!!! 

} 

private ElectricCurrentUnit GetElectricCurrentUnitFromAbbreviation(string abbreviation) 
{ 
    // Is there a better way to determine WHICH ElectricCurrentUnit the target is? 
    if (abbreviation == "A") 
     return ElectricCurrentUnit.Ampere; 
    if (abbreviation == "mA") 
     return ElectricCurrentUnit.Milliampere; 

    return ElectricCurrentUnit.Undefined; 
} 

Mais la liste des unités possibles, nous devons accueillir est grande, donc je n » Je ne veux pas avoir à écrire de cette façon.

Il semble qu'il y ait une meilleure solution.

Serait vraiment apprécier votre avis d'expert dans ce domaine.

+0

@anjdreas Toute entrée sur celui-ci? – JTech

+0

Il y a seulement quelques unités de base pour commencer, et des centaines d'unités dérivées en considérant toutes les combinaisons et puissances. Il semble que vous ayez besoin d'une bibliothèque d'unités différente capable de gérer les unités dérivées de la surcharge de l'opérateur (j'en ai écrit une moi-même). Ce n'est pas facile, mais en regardant [UnitsNet] (https://github.com/anjdreas/UnitsNet) cela ne semble pas être un bon choix pour votre projet. – ja72

+0

C'est un projet de génie électrique et d'après ce que je peux voir dans UnitsNet, le code généré dans l'espace de noms UnitClasses couvre la plupart des choses dont nous avons besoin. Donc, pour le bien de ce qui précède, supposons que nous n'avons pas besoin d'unités autres que celles incluses dans UnitsNet - pourquoi alors diriez-vous que UnitsNet ne convient pas? – JTech

Répondre

0

Cela a été répondu sur github: https://github.com/angularsen/UnitsNet/issues/220

Solution proposée

Cela vous donne des outils pour travailler plus facilement avec les conversions dynamiques, en utilisant des représentations de chaîne de quantités et unités.

  • Nouvelle classe UnitConverter
  • Nouvelle propriété Units sur les quantités, ex: LengthUnit[] Units { get; } sur Length
  • Renommé (obsoleted) UnitClass ENUM à QuantityType pour une nouvelle convention de nommage

Cela permet au scénario suivant:

// Get quantities for populating quantity UI selector 
QuantityType[] quantityTypes = Enum.GetValues(typeof(QuantityType)).Cast<QuantityType>().ToArray(); 

// If Length is selected, get length units for populating from/to UI selectors 
LengthUnit[] lengthUnits = Length.Units; 

// Perform conversion by using .ToString() on selected units 
double centimeters = UnitConverter.ConvertByName(5, "Length", "Meter", "Centimeter"); 
double centimeters2 = UnitConverter.ConvertByAbbreviation(5, "Length", "m", "cm");