Je suis nouveau à la mise en œuvre et Generics ont besoin d'intrants sur 2 questions que je face à:Comment écrire une classe générique qui implémente une interface ayant des méthodes génériques avec des contraintes définies
J'ai une interface ICommand définie comme:
public ICommand
{
List<T> Execute<T>() where T : IValidationResult;
IDomain<T> GetDO<T>() where T : IValidationResult;
}
intentionnellement je l'ai comme non-générique car je dois ajouter une collection de commandes différentes.
Cette interface Je souhaite mettre en œuvre une classe générique appelée PersistCommand comme:
public PersistCommand<TDomainObj,T> : ICommand where TDomainObj : IDomain<T> where T : IValidationResult
{
private TDomainObj _domainObject;//IDomain<T> is an interface
public PersistCommand(TDomainObj TDomainObject)
{
_domainObject = TDomainObject;
}
public IDomain<T> GetDO<T>() where T : IValidationResult
{
return _domainObject as IDomain<T>;
}
public List<T> Execute<T>() where T : IValidationResult
{
//returns a list<T>
}
}
L'intention d'avoir une classe générique est de transmettre ces contraintes de la classe à ces méthodes génériques qui ne se produit malheureusement pas (Je ne sais pas pourquoi?) Quand je compile, j'obtiens un avertissement: Le paramètre Type 'T' a le même nom que le paramètre Type du type externe 'PersistCommand' Ceci est le premier numéro
Le deuxième numéro est: ensemble différent de commandes, InsertCommand, DeleteCommand et UpdateCommand qui héritent de PersistCommand et fonctionne correctement lorsque la méthode Execute() est appelée individuellement.
I ont une classe de commandes qui est utilisé pour l'exécution de plusieurs commandes comme indiqué:
public class CommandManager
{
public virtual IEnumerable<T> Perform<T>(List<ICommand> commandList)
where T : IValidationResult
{
List<T> validationResults = new List<T>();
//fire pre-intent validations
foreach (ICommand command in commandList)
{
validationResults.AddRange(command.GetDomainObject<T>().Validate(command.GetPreIntent()));
}
//fire intent validations
if (validationResults.Count == 0)
{
foreach (ICommand command in commandList)
{
validationResults.AddRange(command.Execute<T>());
}
}
//fire post-intent validations
if (validationResults.Count == 0)
{
foreach (ICommand command in commandList)
{
validationResults.AddRange(command.GetDomainObject<T>().Validate(command.GetPostIntent()));
}
}
return validationResults;
}
}
Tant que le type « T » qui est transmis aux commandes et la méthode de CommandManager.Perform sont les mêmes, Ça marche. Mais j'ai un scénario où nous avons 2 objets de domaine ayant différents types « T » comme:
class Project : IDomain<CustomResult>//CustomResult implements IValidationResult
class Resource : IDomain<AnotherResult>//AnotherResult implements IValidationResult
Quand j'appelle CommandManager.Perform (commandList), il jette une exception à
méthode GetDO montrant un message : référence d'objet non définie à une instance de l'objet »
Toute aide ou idées pour résoudre ce serait apprécié
Salut Dave, J'ai essayé, mais il ne compile pas et le message d'erreur: PersistCommand ICommand.GetDO 'ne pas mettre en œuvre un membre d'interface'() –
Chandrasekhar
je l'ai mis à jour Ma réponse pour couvrir cela, c'est à voir avec la façon dont vous déclarez votre interface. J'ai aussi ajouté des éléments pour simplifier le tout ... HTH –