6
votes

Comment utiliser où pour les opérateurs de génériques classe C #?

Bonjour, j'aimerais avoir une classe:

class Matrix <T>
    where T : // I don't know what to write here
{
    T[][] elements;
}


3 commentaires

Malheureusement, il n'ya aucune contrainte pour les types qui mettent en œuvre des opérateurs spécifiques. Il y a des solutions de contournement que je n'utiliserais pas personnellement, comme la coulée sur dynamique .


contrainte pour seuls les entiers avec une solution éventuelle étant Convertible


Bien qu'une question intéressante, cela fonctionnerait-il en spécifiant implicitement les types (tels que iCatrix pour int et fmatrix pour float )?


4 Réponses :


1
votes

Comme je ne suis pas au courant d'une solution intégrée, vérifiez-y:

public abstract class BaseClass
{
    public static BaseClass operator +(BaseClass p1, BaseClass p2)
    {
        return p1 + p2;
    }

    public static BaseClass operator *(BaseClass p1, BaseClass p2)
    {
        return p1 * p2;
    }
}

public class ChildClass : BaseClass
{
}

public class Matrix <T> where T : BaseClass
{
    T[][] elements;
}


2 commentaires

S'il y a une autre classe prenant en charge + et * mais n'hérite pas basoclass cela ne fonctionnera pas. Par exemple int


@Default En effet, merci d'avoir souligné cela. J'ai mis à jour la réponse pour ajouter cette restriction.



1
votes

Peut être de cette façon sera utile pour quelqu'un. Vous pouvez améliorer cela en mettant l'ajout, multiplicez des fonctions dans la classe de la bibliothèque de tissu.

mise à jour Peut-être mettre en place des opérateurs de Publier de Jerkimball dans le Fondateur xxx

update 2

Il suffit de fournir un accès à une propriété comme celle-ci: xxx

et vous pouvez faire ceci: xxx


2 commentaires

De cette façon, je ne peux pas donner de la valeur à l'élément (comme 0 ou un nombre, je ne peux également pas les jeter à INT ou à un type non nullable)


Pourriez-vous donner un exemple de ce que vous ne pouvez pas faire?



2
votes

Je vous recommanderais vivement de jeter un coup d'œil à la bibliothèque "Miscutil" de MM Messrs Skeet et Gravell:

http://www.yoda.arachsys.com/cshaarp/miscutil/

contenu est un incroyable implémentation "opérateurs de mathématiques génériques", qui devrait gérer joliment avec votre tente de créer une classe de mathématiques de matrice générique. Cela me rappelle effectivement (un peu) de python et de la manière dont il gère le référencement des fonctions de l'opérateur directement.

(à part à @ jon-Skeet: toute chance de cela en faisant partie de Nuget?)

Quelques exemples d'usages de leurs tests: xxx


0 commentaires

2
votes

Ce n'est pas possible car le type générique non contraint est supposé être de type objet , qui ne définit pas les opérateurs arithmétiques. Par conséquent, il semble que vous devez spécifier une interface.

mais, les types primitifs (int32, double, etc.) définissent efficacement les opérations arithmétiques en tant que méthodes statiques (en réalité, le compilateur les traite spécialement et génère le code en ligne) et une interface en C # ne peut pas définir des méthodes statiques (bien que la conception du CLR le lui permet de lui permettre). Par conséquent, aucune interface n'est écrite en C # qui satisfait aux exigences de soutenir les opérations arithmétiques; Même si cela pourrait être écrit, les types primitifs ne l'héritent pas, de sorte que cela ne fonctionnerait toujours pas.

Le résultat final est qu'il n'ya aucun moyen de faire ce que vous voulez en C #.

Si vous l'essayerez, vous obtenez une erreur similaire à xxx

si vous faites une recherche sur le Web pour ce message, vous trouverez diverses discussions sur les solutions de contournement possibles .


0 commentaires