La création d'une bibliothèque de Mathématiques à l'aide de médicaments Génériques en C#
Est-il possible d'utiliser les génériques pour créer une bibliothèque de Mathématiques qui ne dépend pas du type de base choisi pour stocker des données?
En d'autres termes, supposons que je veux écrire une Fraction de la classe. La fraction peut être représenté par deux entiers ou deux lits doubles ou d'autres joyeusetés. La chose importante est que les quatre opérations arithmétiques de base sont bien définis. Donc, j'aimerais être capable d'écrire Fraction<int> frac = new Fraction<int>(1,2)
et/ou Fraction<double> frac = new Fraction<double>(0.1, 1.0)
.
Malheureusement, il n'existe pas d'interface représentant les quatre opérations de base (+,-,*,/). Personne n'a trouvé un réaliste, réalisable la mise en oeuvre de cette?
Vous devez vous connecter pour publier un commentaire.
Ici est un moyen d'abstraire les opérateurs, ce qui est relativement indolore.
Si vous ne parvenez pas à mettre en œuvre un type que vous utilisez, vous obtiendrez un échec à l'exécution au lieu de au moment de la compilation (c'est mauvais). La définition de la
MathProvider<T>
implémentations est toujours le même (mauvais). Je suggère que vous venez d'éviter de le faire en C# et F# ou une autre langue mieux adaptés à ce niveau d'abstraction.Edit: Fixe les définitions d'ajouter et de soustraire pour
Fraction<T>
.Une autre intéressante et simple chose à faire est de mettre en œuvre un MathProvider qui fonctionne sur un arbre de syntaxe abstraite. Cette idée immédiatement des points pour faire des choses comme la différentiation automatique: http://conal.net/papers/beautiful-differentiation/
public abstract double DivideToDouble (T a, T b)
Je crois que cela répond à votre question:
http://www.codeproject.com/KB/cs/genericnumerics.aspx
Voici un problème subtil qui vient avec des types génériques. Supposons qu'un algorithme implique la division, dire l'élimination de Gauss pour résoudre un système d'équations. Si vous passez dans les entiers, vous obtiendrez une réponse erronée parce que vous devrez mener à bien entier division. Mais si vous passez dans le double arguments qui se produisent ont une valeur entière, vous aurez le droit de réponse.
La même chose se produit avec des racines carrées, comme dans la factorisation de Cholesky. La factorisation d'un entier de la matrice va aller mal, alors que la factorisation d'une matrice de doubles qui ont une valeur entière sera fine.
Tout d'abord, votre classe devrait limiter le paramètre générique de primitives ( public class Fraction où T : struct, new() ).
Deuxième, vous aurez probablement besoin de créer implicite fonte des surcharges de sorte que vous pouvez gérer la conversion d'un type à l'autre sans que le compilateur de pleurer.
Troisième, vous pouvez surcharger les quatre opérateurs de base ainsi à rendre l'interface plus souple lors de la combinaison des fractions de différents types.
Enfin, vous devez tenir compte de la façon dont vous êtes la manipulation arithmétique des cours et underflows. Une bonne bibliothèque va être très explicite dans la façon dont il traite les débordements; sinon, vous ne pouvez faire confiance à l'issue des opérations de différents fraction types.