2017-10-11 2 views
3

j'ai une classe générique définie comme suit:Veiller à ce paramètre sur la méthode générique est la base de paramater dans la même classe

public abstract class BaseValidator<T> : IValidator<T> where T: IEntity 
{ 
    //some methods and parameters here 
    protected void Include<E>(IValidator<E> validator) where E : class , IEntity 
    { 
     if (typeof(E) != typeof(T).BaseType) 
     { 
      throw new ArgumentException($"Generic class Validator<T> must only Include Validators for base classes"); 
     } 
     //Some business logic around connecting validators 
    } 
} 

La méthode Inclure est conçu pour prendre un paramètre Validator, il utilise pour lier validateurs l'un à l'autre, semblable à une chaîne de responsabilité des validateurs. J'ai actuellement la vérification du temps d'exécution pour m'assurer que E est une classe de base de T mais je voudrais déplacer ceci pour compiler la vérification de temps.

J'ai essayé d'ajouter une deuxième clause where à la méthode Inclure comme suit:

where T:E 

studio Cependant visuel se plaint que la méthode Inclure ne définit pas un paramètre de type « T »

Si Je définis un paramètre de type Je reçois un message indiquant que le paramètre de type 'T' a le même nom que le paramètre type sur la classe externe.

Comment puis-je m'assurer que le type générique transmis à ma méthode est la classe de base que mon T implémente?


Edit 1:

public class BankAccountValidator : BaseValidator<BankAccount> 
    { 
     public BankAccountValidator(IValidator<OwnedProduct> validator) 
     { 
      Include(validator); 
      //Some logic here 
     } 
    } 

Dans ce cas BankAccount implémente OwnedProduct. Donc, quand une méthode de validation est appelée sur BankAccount, elle appelle aussi validate sur OwnedProduct.

Je veux appliquer que vous ne pouvez pas passer à BankAccountValidator un autre BankAccountValidator ou si j'ai un type OwnedCredit dont BankAccount ne dérive pas que je ne peux pas transmettre le OwnedCreditValidator au constructeur.

Il existe un grand nombre de validateurs et le fait de le typer fortement comme ceci m'empêcherait de rencontrer des problèmes d'exécution.

+0

Vous ne pouvez pas limiter le paramètre de type niveau de la classe dans la méthode de cette classe, n'a même pas beaucoup de sens. Dites que vous étiez capable de faire cela, maintenant 'T' devrait hériter de' E'. Ensuite, vous ajoutez une autre méthode avec un paramètre de type 'F' et dites que' T' devrait en hériter. Maintenant, 'T' devrait hériter à la fois de' E' et 'F'. – Evk

+1

Si je comprends bien, vous devriez être capable de changer la signature de la méthode 'protected void Include (validateur IValidator ) {...}'? Parce que 'T' est déjà défini? Peut-être ne pas l'avoir, cependant. – thmshd

+0

OK J'ai supprimé ma réponse parce que je n'avais pas reçu votre question auparavant. – thmshd

Répondre

2
public abstract class BaseValidator<T, E> : IValidator<T> 
    where E: IEntity 
    where T: E 
{ 
    //some methods and parameters here 
    protected void Include(IValidator<E> validator) 
    {   
     //Some business logic around connecting validators 
    } 
} 

public class BankAccountValidator : BaseValidator<BankAccount, OwnedProduct> 
{ 
    public BankAccountValidator(IValidator<OwnedProduct> validator) 
    { 
     Include(validator); 
     //Some logic here 
    } 
} 

Si OwnedProductValidator peut se valider, puis:

public class OwnedProductValidator : IValidator<OwnedProduct> 
{ 
    // IValidator interface implementation 
} 

public class Program 
{ 
    public static void Main() 
    { 
     var ownedProductValidator = new OwnedProductValidator();     
     var bankAccountValidator = new BankAccountValidator(ownedProductValidator); 
    } 
} 

Si OwnedProductValidator a besoin d'une autre validation de classe, puis:

public class OwnedProductValidator : BaseValidator<OwnedProduct, SomeOtherClass>{} 
+0

Comment puis-je utiliser BaseValidator pour ma classe de base?Quel serait le second paramètre pour OwnedProductValidator? – ObiEff

+1

Désolé, j'ai été suivi d'un autre problème et j'ai oublié de marquer cela comme la réponse. Plutôt que de suivre votre code exactement, j'ai laissé le validateur de base tel qu'il était et créé une classe secondaire qui implémente le validateur de base et a les restrictions d'héritage. Merci – ObiEff