Pregunta

Tengo un método que estoy escribiendo que llama a otro método sobrecargado dentro de él. Me gustaría escribir solo un método externo, ya que el parámetro del método externo se pasa al interno. ¿Hay alguna manera de hacer esto?

Intenté usar genéricos, pero no sé lo suficiente sobre esto, así que no funciona:

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

Sé que puedo hacer esto:

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

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

Pero prefiero hacer esto de la manera correcta en lugar de copiar / pegar el código. ¿Cuál es la mejor manera de lograr esto?

¿Fue útil?

Solución

Puede hacer esto en C ++ pero no en C # (a menos que el método interno también pueda ser genérico en lugar de sobrecargado).


Alternativamente (si no acepta 'no' como respuesta), puede hacer un cambio de tipo de ejecución en tiempo de ejecución, como por ejemplo ...

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

... pero obviamente esto es un tiempo de ejecución, no una verificación de tiempo de compilación.

  

Pero prefiero hacer esto de la manera correcta en lugar de copiar / pegar el código.

También puede escribir software para escribir sus métodos externos (por ejemplo, usando las clases System.CodeDom) en lugar de escribirlos a mano, pero esto probablemente sea más problema de lo que vale.

Otros consejos

Como dijeron los demás, realmente no puedes hacer lo que estás tratando de hacer y la opción que estableciste en tu pregunta es la mejor opción.

En realidad, tendría que convertir el valor si usa el genérico. De lo contrario, puede abatir aceptando un Objeto como ChrisW sugiere.

 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
            }

Aquí hay un enlace a la descripción general de los genéricos: http: // msdn .microsoft.com / es-es / library / ms172193.aspx

Según su descripción, esto parece una optimización excesiva.

¿Qué tal:

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

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

Puede usar un tipo dynamic para diferir la resolución de sobrecarga hasta el tiempo de ejecución.

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

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

Advertencia Las expresiones de tipo dinámico no se resuelven o tipo verificado por el compilador. Y también puede haber una penalización de rendimiento.

Si OuterMethod siempre llama a InnerMethod, e InnerMethod solo acepta un int o una cadena, entonces OuterMethod < T > no tiene ningún sentido.

Si la diferencia solo es que uno llama a InnerMethod (int) y el otro llama a InnerMethod (string), podría hacer algo como esto:

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, tengo una situación similar, es un método de control de acceso en mi lógica de negocios.

Hay una función de guardar que se podría aplicar a cualquiera de mis objetos de capa de persistencia.

para que se vea así

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

Sin embargo, cada vez que tengo un código personalizado para ciertas entidades en términos de Control de acceso, escribí lo siguiente, busca un método más adecuado para la pregunta usando System.Reflection, " ¿puede esta entidad ser escrita por este usuario? "

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

Ahora, cada vez que agrego o elimino un método, solo tengo que agregarlo o eliminarlo en un solo lugar

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top