Domanda

Ho un metodo che sto scrivendo che sta chiamando un altro metodo sovraccarico al suo interno. Vorrei scrivere solo un metodo esterno, poiché il parametro al metodo esterno viene passato a quello interno. C'è un modo per farlo?

Ho provato a usare generics, ma non ne so abbastanza, quindi non funziona:

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

So di poterlo fare:

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

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

Ma preferirei farlo nel modo giusto invece di copiare / incollare il codice. Qual è il modo migliore per raggiungere questo obiettivo?

È stato utile?

Soluzione

Puoi farlo in C ++ ma non in C # (a meno che il metodo interno non possa essere generico anziché sovraccarico).


In alternativa (se non si accetta "no" per una risposta), è possibile eseguire un tipo di commutazione di runtime, ad esempio ...

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

... ma ovviamente questo è un tempo di esecuzione, non un controllo in fase di compilazione.

  

Ma preferirei farlo nel modo giusto invece di copiare / incollare il codice.

Puoi anche scrivere software per scrivere i tuoi metodi esterni (ad es. usando le classi System.CodeDom) invece di scriverli a mano, ma questo probabilmente è più un problema di quanto valga la pena.

Altri suggerimenti

Come hanno detto gli altri, non puoi davvero fare quello che stai cercando di fare e l'opzione che hai dichiarato nella tua domanda è la scommessa migliore.

Dovresti effettivamente convertire il valore se usi il generico. Altrimenti puoi effettuare il downcast accettando un oggetto come suggerisce 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
            }

Ecco un link alla panoramica di Generics: http: // msdn .microsoft.com / en-us / library / ms172193.aspx

Dalla tua descrizione sembra un'ottimizzazione eccessiva.

Che ne dici di:

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

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

È possibile utilizzare un tipo dynamic per rinviare la risoluzione di sovraccarico fino al runtime.

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

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

Avvertenza Le espressioni di tipo dinamico non vengono risolte o tipo controllato dal compilatore. E potrebbe esserci anche una penalità prestazionale.

Se OuterMethod chiama sempre InnerMethod e InnerMethod accetta solo un int o una stringa, allora OuterMethod < T > non ha alcun senso.

Se la unica differenza è che una chiama InnerMethod (int) e l'altra chiama InnerMethod (stringa), potresti fare qualcosa del genere:

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 ho una situazione simile, è un metodo di controllo degli accessi nella mia logica aziendale.

Esiste una funzione di salvataggio che potrebbe essere applicata a qualsiasi dei miei oggetti del livello di persistenza.

in questo modo

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

Tuttavia, se ho un codice personalizzato per determinate entità in termini di controllo degli accessi, quindi ho scritto quanto segue, cerca un metodo più adatto alla domanda usando System.Reflection, " può questa entità essere scritta da questo utente? "

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"));
        }

Ora ogni volta che aggiungo o rimuovo un metodo, devo solo aggiungerlo o rimuoverlo in un unico posto

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top