0
votes

Renvoyez la classe générique plus héritée de la méthode?

J'ai une telle interface: xxx pré>

et classe qui implémente cette interface: p> xxx pré>

J'ai aussi une interface pour les processeurs d'importation: p> xxx pré>

et il y a l'une des implémentations de cette interface: p> xxx pré>

maintenant je veux créer une usine pour instancier ce type des processeurs. J'ai une interface: p> xxx pré>

et j'essaie de créer une implémentation: p> xxx pré>

mais j'ai eu exception: p>

Erreur CS0266 ne peut pas convertir implicitement le type 'MaterialPortProcesseur' vers IIMPORTPROCESSOR CODE>. Une conversion explicite existe (manquez-vous un casting?) P> BlockQuote>

C'est correct. Mais je ne peux pas utiliser out code> mot-clé pour faire iimportprocessor code> covariance parce que j'utilise tmodel code> comme paramètre d'entrée de processus (méthode Tmodel) méthode. p>

Y a-t-il des façons de refacteur de ce code pour le faire fonctionner? p>

édité fort>

J'ai décidé de Donnez des informations supplémentaires sur la façon dont je prévois d'utiliser cette usine. P>

var deserializer = _deserializerFactory.Get(/*some parameters*/);
var importProcessor = _importProcessorFactory.Get(someEunmValue);

var data = deserializer.Deserialize(file);
importProcessor.Process(data);


4 commentaires

Avez-vous essayé d'ajouter un casting?


Oui, j'ai essayé. Mais il y a une erreur d'exécution dans ce cas.


Coz iimportProcessor n'est pas implémenté par matérialimportprocessor classe.


Oui, mais MaterialPortProcessor implémente IIMPORTProcessor , où MaterialPortModel implémente IImpportModel. Il peut être de travailler si vous utilisez le mot-clé «OUT». Par exemple: Interface publique IImpoCrocessor Où Tmodel: IImpportModel; Mais je ne peux pas le faire, car Tmodel est le paramètre d'entrée pour 'processus ()'


5 Réponses :


-1
votes

Avez-vous essayé d'ajouter un casting comme l'utilisateur Devflamur mentionné, en utilisant l'opérateur?


1 commentaires

Lorsque j'essaie d'utiliser «As», l'usine de l'opérateur renvoie NULL au lieu de l'instance de processeur. Lorsque j'utilise Explicit Cast, je reçois une exception d'exécution.



0
votes

Vous devez passer à:

public interface IImportModel
{

}

public class MaterialImportModel: IImportModel
{
    public string Name { get; set; }
}

public class CompanieImportModel: IImportModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public interface IImportProcessor
{
     void Process(IImportModel model);
}

public class MaterialImportProccessor : IImportProcessor
{
    public void Process(IImportModel model)
    {
        var obj = (MaterialImportModel) model;

        // do some logic here
    }
}

public interface IImportProcessorFactory
{
    IImportProcessor Get();
}


public class ImportProcessorFactory 
{
    public IImportProcessor Get(Parameter parameter)
    {
         switch (Parameter) 
         {
            case "Materials":
                 IImportProcessor processor = new MaterialImportProccessor();
                 return processor;

            case "Companies":
                IImportProcessor processor = new CompaniesImportProccessor();
                return processor;
         }
    }
}


7 commentaires

Dans ce cas, je dois mettre en œuvre une nouvelle usine pour chaque modèle d'importation. Parce que je devrais importer non seulement des matériaux, mais aussi des entreprises, des utilisateurs, etc.


J'ai édité ma question pour expliquer pourquoi je ne peux pas utiliser l'usine générique. Merci!


Si vous ne pouvez pas utiliser la classe générique, vous pouvez utiliser la méthode générique iimportprocessor Get () Où Tmodel: iimportmodel


Non, je ne peux pas utiliser également la méthode générique. Parce que sur l'étape où j'essaie d'obtenir un processeur d'importation, je ne connais pas le type pour l'utiliser dans la méthode générique. J'ai seulement énumé. Et je veux obtenir un processeur d'importation concrets de cet énumé de l'usine.


Vous ne devriez donc pas utiliser générique, vous pouvez lancer votre interface en classe dans MaterialImportProcessor.Processeur.


Oui, je devrai le faire au cas où je ne pouvais pas trouver une meilleure solution. Je voulais juste éviter de lancer dans chaque processeur. Merci!


Vous ne pouvez pas lancer une classe à une interface que vous devriez lancer une interface à une classe. Stackoverflow.com/Questtions/10833946/...



0
votes

mise à jour forte>

https://dotnetfiddle.net/hytwin

envisager d'utiliser dynamique code> mot-clé pour votre usine: p> xxx pré>

Vous pouvez donc l'utiliser similaire à celui-ci: P >

        var factory = new ImportProcessorFactory();
        var material = factory.Get(Parameter.Materials);
        var company = factory.Get(Parameter.Companies);


        var model = new MaterialImportModel();
        model.MaterialName = " Metal ";
        material.Process(model);

        var cModel = new CompanyImportModel();
        cModel.CompanyName = "Build Metal Company";
        company.Process(cModel);


7 commentaires

L'usine doit retourner non seulement matérialisateur. Cela devrait être générique. Parce que j'aurai beaucoup de transformateurs d'importation. À cause de cela, je ne peux pas restreindre l'usine d'utiliser MatérialImportModel.


Merci. Mais je voulais éviter l'usine générique. Parce que sur pas lorsque j'essaie d'obtenir un processeur d'importation, je ne connais pas le type de modèle d'importation concret. J'ai seulement énumé. Et l'usine doit me renvoyer un processeur d'importation concrets de cet énumé. J'ai édité ma question et j'ai donné des informations supplémentaires sur la manière dont je prévois d'utiliser l'usine.


@Vladb Vérifiez à nouveau maintenant, j'ai modifié la mise en œuvre de la classe matérialisateur et simplified le


Merci. Je connaissais la solution avec la coulée. Mais je voulais éviter cela. Je vais devoir y aller si je ne pouvais pas trouver une meilleure solution. De plus, j'ai besoin de Generic IImprocessor, car je prévois d'enregistrer tous les processeurs d'importation dans DI Contener. Pour ce faire, ils devraient être paramétrés. Sinon, je ne peux enregistrer qu'un.


@Vladb envisagez ensuite d'utiliser Dynamic, j'ai mis à jour l'URL de violon espère que cela aide cette fois ce temps :)


Cela semble bon! Merci beaucoup. J'ai fourni une solution avec une classe abstraite supplémentaire et «comme» opérateur. Vous pouvez le lire. Je penserai à ces deux solutions. Maintenant, je ne connais pas beaucoup de dynamique. Mais ça ressemble presque à je voulais!


@Vladb bien d'entendre ça! N'oubliez pas ensuite de marquer la bonne réponse :) Bravo



0
votes

Mise à jour 2

Ceci est le meilleur que je puisse aujourd'hui. p> xxx pré>

sortie h2> xxx pré>

update 1 h1>

déposer l'interface modèle et faire prendre le processeur T p> xxx pré>

avec cette configuration Les choses doivent contenir ensemble. p> xxx pré>


(ancienne réponse) em> p>

Je pense faire iimportprocessor code> non générique rendre votre modèle beaucoup plus simple et supprimé toute une classe de problèmes. p> xxx pré>


Le processeur de matériau doit mettre en œuvre processus code> qui prend l'interface, non une classe concrète. Sinon, cela ne répond pas au contrat et b) vous vous débarrassez des avantages des interfaces :). P>

public class MaterialImportProcessor : IImportProcessor
{
    public void Process(IImportModel model)
    {
        // do some logic here
    }
}


11 commentaires

Oui. Je suis d'accord. Si je ne pouvais pas trouver d'autres solutions, je devrai utiliser cette approche. Mais dans ce cas, je dois lancer Iimportmodel sur une classe concrete dans chaque processeur que je voulais éviter. De plus, je peux utiliser juste un objet. Merci pour l'aide.


Si vous devez vous lancer, alors pourquoi ne pas arrêter de prétendre qu'il y a des interfaces ici? Utilisez simplement des classes en béton.


Si vous moulez pour Nom , faites-la partie de l'interface modèle.


J'ai ajouté une interface juste en tentative d'écrire des usines génériques. Je veux avoir une usine qui retournera un processeur d'importation concrets par certains paramètres d'entrée. J'aurai beaucoup de modèles à importer et chacun d'entre eux fonctionne avec du type concret. En usine, je ne peux pas utiliser de type concret.


"usines génériques" - génériques! = interfaces. Faisons-le génériques.


@Vladb j'ai mis à jour ma réponse voir sur le lien Fiddle


Oui je sais. Mais mon usine devrait retourner une certaine classe de base. À cause de cela j'ai ajouté une interface. Je peux utiliser une classe abstrait au lieu de cela, mais cela ne fait rien dans mon cas. De plus, je ne peux pas faire d'usine générique (je l'ai décrit en question). Mais cela devrait toujours renvoyer un processeur d'importation générique. Je devrais peut-être refactuer ce code pour atteindre cet objectif. Mais je ne sais pas comment. Si vous savez me dire, s'il vous plaît.


Si j'ai compris votre exemple correct, je devrais créer une nouvelle usine pour chaque processeur d'importation. Mais je veux créer une seule usine qui créera un processeur d'importation approprié par une valeur ENUM que je passerai pour obtenir () la méthode d'usine.


Je ne peux pas envoyer de données via le constructeur car je dois enregistrer des processeurs d'importation dans DI Contener. De plus, chaque processeur d'importation peut avoir ses propres dépendances.


Embrouillé. Je pensais que nous écrivions l'usine. Si les processeurs possibles sont déjà disponibles et que nous devons simplement demander un selon le type, c'était une perte de temps ...


Je planifie d'enregistrer tous les processeurs d'importation dans DI Contener. (En raison de ce qu'ils devraient être génériques pour implémenter différentes interfaces). Après cette usine de processeur d'importation à l'aide de DI Conteneur, schoulez-les par une énumération. J'ai simplifié ma question pour éviter des informations supplémentaires. Quoi qu'il en soit, je devrais résoudre le problème que j'ai décrit. Je suppose que cela ne concerne pas le temps que nous utilisons un conteneur DI à l'intérieur ou non. Désolé de malentendus.



0
votes

J'ai décidé d'ajouter une classe abstraite supplémentaire: xxx

et modifié matérialImportsor xxx


0 commentaires