Question

J'ai une série de cours dans un projet qui tous font essentiellement la même chose, mais sur différents objets. En raison de certains d'entre eux ayant été codifiées à différents moments et par différentes personnes il y a une certaine incohérence dans la dénomination. Je veux mettre à jour mon code d'une manière qui mettra en application une certaine cohérence non seulement dans les objets actuels, mais de nouveaux qui sont créés dans l'avenir. Ma compréhension de la programmation me porte à croire que j'ai besoin, soit une classe de base ou d'une interface, mais je ne peux pas comprendre comment obtenir soit au travail. Les méthodes que je veux avoir sont:

internal BusinessObject MethodA(EntityObject entity)
internal Void MethodB(EntityContext context, BusinessObject obj, EntityObject entity)

La question que j'ai est que dans chaque classe la « BusinessObject » et « EntityObject » sera différent par exemple dans l'un, il est peut-être « CarObject et CarEntity » et dans un autre, il serait « BusObject et BusEntity ». Je veux encore les deux méthodes et je veux toujours les nom et METHODA MethodB Je veux juste échange sur les types d'objets réels dans la mise en œuvre. Les mises en œuvre elles-mêmes seront différents parce qu'ils utilisent des objets différents.

Je sais que les types d'objets au moment de la compilation et la nécessité de pouvoir accéder aux propriétés des objets si génériques sont utilisés que j'ai besoin de lancer le générique comme le type correct dans la mise en œuvre. Aussi la mise en œuvre de METHODA exige la création d'un "nouveau" BusinessObject dire "BusinessObject x = new BusinessObject ()" si cela fait une différence.

J'ai essayé d'utiliser une interface avec les génériques dans les méthodes et aussi une classe de base avec des méthodes abstraites mais je ne l'ai pas été en mesure de comprendre comment obtenir soit au travail.

Quelle est la meilleure façon de gérer cela? Exemple de code serait très apprécié.

Était-ce utile?

La solution

Les médicaments génériques sont le chemin

Je déclarerais une interface (ou classe de base si vous préférez cette route) le long de ces lignes:

internal interface IEntityContext<TEntity>
{
 ???
}

internal interface IMyInterfaceName<TEntity, TBusinessObject>
{
TBusinessObject MethodA(TEntity entity);
Void MethodB(IEntityContext<TEntity> context, TBusinessObject obj, TEntity entity);
}

Alors quand il vient à vous mettre en œuvre la classe:

class MyClassThatDoesThisStuff : IMyInterfaceName<Farm, FarmBo>
{
    internal FarmBo MethodA(Farm entity);
    internal Void MethodB(IEntityContext<Farm> context, FarmBo obj, Farm entity);

}

etc ...

Vous pouvez également appliquer que vos classes descendent de quelque chose:

interface IMyInterfaceName<TEntity, TBusinessObject> 
            where TEntity : EntityBase,
                  TBusinessObject : BusinessObjectBase
{
...
}

Autres conseils

Juste pour montrer la solution avec une classe de base abstraite, voir la réponse Neils pour plus d'informations ...

public abstract class BaseClass<A,B> {
    internal abstract A MethodA(B entity);
    internal abstract void MethodB(EntityContext context, A obj, B entity);
}

étendons ensuite cette classe:

public class AClass : BaseClass<BusinessObject, EntityObject> {
    internal override BusinessObject MethodA(EntityObject entity) {...}
    internal override void MethodB(EntityContext ctx, BusinessObject obj, EntityObject entity) {...}
}

Il y a vraiment trois approches:

  1. Génériques: Si vous spécifiez objet conteneur de telle manière qu'il est indépendant des types de BusinessObject et EntityObject. Vous pouvez étendre qu'un peu de restrictions sur les types d'objets que le générique accepte comme paramètre avec des contraintes génériques. Le grand défi est qu'il est difficile d'utiliser effectivement BusinessObject et EntityObject sans coulée et d'autres opérations relativement dangereuses.

  2. Héritage: Dans ce cas, vous implémentez BusinessObject en tant que classe de base, et exigent que tous les objets utilisés en tant que paramètre provenir de cela, et de même avec EntityObject. Ensuite, vous pouvez mettre toutes les méthodes que vous avez réellement besoin d'utiliser dans la classe de base (et si nécessaire les override dans les classes dérivées.)

  3. Interfaces: Ceci est un moyen de moitié entre les deux. Vous dites que BusinessObject et EntityObject sont des interfaces (tradtionally leurs noms commencent avec moi, comme dans IBusinessObject etc.), vous indiquez dans l'interface les méthodes que vous avez besoin d'BusinessObject ou EntityObject à mettre en œuvre, et peuvent par conséquent les appeler dans votre récipient objet.

Donc, avec les informations limitées dont vous donnez, il est impossible de dire qui est le plus approprié. Cependant, ce sont vos trois choix fondamentaux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top