Question

J'ai une méthode que j'écris et qui appelle une autre méthode surchargée à l'intérieur. J'aimerais n'écrire qu'une seule méthode externe, car le paramètre de la méthode externe est transmis à la méthode interne. Y a-t-il un moyen de le faire?

J'ai essayé d'utiliser des génériques, mais je n'en sais pas assez pour que cela ne fonctionne pas:

public void OuterMethod<T>(T parameter)
{
    InnerMethod(parameter); // InnerMethod accepts an int or a string
}

Je sais que je peux le faire:

public void OuterMethod(string parameter)
{
    InnerMethod(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethod(parameter);
}

Mais je préférerais procéder de la bonne façon plutôt que de copier / coller du code. Quel est le meilleur moyen d'y parvenir?

Était-ce utile?

La solution

Vous pouvez le faire en C ++ mais pas en C # (à moins que la méthode interne puisse également être générique au lieu d'être surchargée).

Alternativement (si vous ne prenez pas "non" comme réponse), vous pouvez utiliser un type d'exécution, comme par exemple ...

public void OuterMethod(object parameter)
{
    if (parameter is int)
        InnerMethod((int)parameter);
    else if (parameter is string)
        InnerMethod((string)parameter);
    else
        throw new SomeKindOfException();
}

... mais évidemment, il s'agit d'une exécution, pas d'une vérification à la compilation.

  

Mais je préférerais procéder de la bonne façon au lieu de copier / coller du code.

Vous pouvez également écrire un logiciel pour écrire vos méthodes externes (par exemple, en utilisant des classes System.CodeDom) au lieu de les écrire à la main, mais cela représente probablement plus de problèmes que cela ne vaut la peine.

Autres conseils

Comme les autres l'ont dit, vous ne pouvez pas vraiment faire ce que vous essayez de faire et l'option que vous avez indiquée dans votre question est le meilleur pari.

Vous devrez en fait convertir la valeur si vous utilisez le générique. Sinon, vous pouvez réduire le nombre de points en acceptant un objet comme le suggère ChrisW.

 public void OuterMethod<T>(T parameter) 
            {
                T temp = parameter;
                if (temp is string )
                    InnerMethod(Convert.ToString(temp));
                if (temp is int)
                    InnerMethod(Convert.ToInt32(temp));// InnerMethod accepts an int or a string
            }

Voici un lien vers la présentation des génériques: http: // msdn .microsoft.com / fr-us / library / ms172193.aspx

D'après votre description, cela ressemble à une suroptimisation.

Que diriez-vous de:

public void OuterMethod(string parameter)
{
    InnerMethod(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethod(parameter**.ToString()**);
}

Vous pouvez utiliser un type dynamic pour différer la résolution de la surcharge jusqu'au moment de l'exécution.

public void OuterMethod(dynamic parameter)
{
    InnerMethod(parameter);
}

public void InnerMethod(int parameter) { }
public void InnerMethod(string parameter) { }

Avertissement Les expressions de type dynamique ne sont pas résolues ou type vérifié par le compilateur. Il pourrait également y avoir une pénalité de performance.

Si OuterMethod appelle toujours InnerMethod et que InnerMethod accepte uniquement un int ou une chaîne, alors OuterMethod < T > n'a aucun sens.

Si la seule différence est que l'un d'entre eux appelle InnerMethod (int) et que l'autre appelle InnerMethod (chaîne), vous pouvez procéder de la manière suivante:

public void OuterMethod(string parameter)
{
    InnerMethodA(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethodA(parameter);
}

private void InnerMethodA(object parameter)
{
    // Whatever other implementation stuff goes here

    if (parameter is string)
    {
        InnerMethodB((string) parameter);
    }
    else if (parameter is int)
    {
        InnerMethodB((string) parameter);
    }
    else
    {
        throw new ArgumentException(...);
    }
}

private void InnerMethodB(string parameter)
{
    // ...
}

private void InnerMethodB(int parameter)
{
    // ...
}

Ok, j'ai une situation similaire, c'est une méthode de contrôle d'accès dans ma logique métier.

Il existe une fonction de sauvegarde qui pourrait être appliquée à n’importe quel de mes objets de couche de persistance.

donc ça ressemble à ça

public static Save<T>(AccessControl.User user,T entity) where T:PersistanceLayerBaseClass
{
    if(CanWrite(user, entity))
    {
        entity.save();
    }
    else
    {
        throw new Exception("Cannot Save");
    }
}

Quel que soit le code de contrôle d'accès que j'ai pour certaines entités en termes de contrôle d'accès, j'ai donc écrit ce qui suit: il s'agit d'une méthode plus appropriée à la question utilisant System.Reflection, & "; cette entité peut-elle être écrite cet utilisateur? "

public static Boolean CanWrite<T>(AccessControl.User user, T entity) where T : PersistanceLayerBaseClass
        {
            int? clubId = null;
            MethodInfo methodInfo = entity.GetType().GetMethod("CanWrite", new Type[] { typeof(AccessControl.User), entity.GetType() });
            if(methodInfo != null)
            {
                return (Boolean)methodInfo.Invoke(null, new object[] { user, entity }) ;
            }
            else 
            {
                //generic answer
            }
            return HasRole(user.UserID, "Administrator") || (clubId.HasValue && user.MemberObject.ClubId == clubId.Value && HasRole(user.UserID, "AdministerClub"));
        }

Maintenant, chaque fois que j'ajoute ou supprime une méthode, il suffit de l'ajouter ou de la supprimer à un endroit

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