Pergunta

Eu tenho um método que eu estou escrevendo que está chamando outro método sobrecarregado dentro dela. Eu gostaria apenas para escrever um método externo, uma vez que o parâmetro para o método externa está sendo passado para o interior. Existe uma maneira de fazer isso?

Eu tentei usar os genéricos, mas eu não sei o suficiente sobre isso para que ele não está funcionando:

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

Eu sei que eu posso fazer isso:

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

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

Mas eu prefiro fazer isso do jeito certo em vez de copiar o código / colar. Qual é a melhor maneira de conseguir isso?

Foi útil?

Solução

Você pode fazer isso em C ++, mas não em C # (a menos que o método interno também pode ser genérica, em vez de sobrecarregados).


Como alternativa (se você não vai aceitar 'não' como resposta), você pode fazer um interruptor de tempo de execução do tipo, como por exemplo ...

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

... mas, obviamente, este é um tempo de execução, não uma verificação em tempo de compilação.

Mas eu prefiro fazer isso do jeito certo em vez de copiar o código / colar.

Você também pode software de escrita para escrever os seus métodos externos (por exemplo, usando classes System.CodeDom) em vez de escrevê-los à mão, mas isso é provavelmente mais problemas do que vale a pena.

Outras dicas

Como os outros disseram, você não pode realmente fazer o que você está tentando fazer e a opção que afirmou na sua pergunta é a melhor aposta.

Você realmente tem que converter o valor se você usar o genérico. Caso contrário, você pode downcast ao aceitar um objeto como ChrisW sugere.

 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
            }

Aqui está um link para a visão geral de Genéricos: http: // MSDN .microsoft.com / en-us / library / ms172193.aspx

De sua descrição este parece ser o excesso de otimização.

Como sobre: ??

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

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

Você pode usar um tipo dynamic adiar a resolução de sobrecarga até run-time.

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

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

Aviso Expressões do tipo dinâmico não são resolvidos ou digite verificada pelo compilador. E pode haver uma penalidade de desempenho também.

Se OuterMethod sempre chama InnerMethod e InnerMethod só aceita um int ou string, então OuterMethod não faz qualquer sentido.

Se o única diferença é que se chama InnerMethod (int) e as outras chamadas InnerMethod (string) você poderia fazer algo parecido com isto:

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 eu tenho uma situação semelhante, o seu método de controle de acesso na minha lógica de negócios.

Há uma função de economia que poderia ser aplicada a qualquer um dos meus Persistência objetos da camada.

tão parecida com esta

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

Como sempre tenho algum código personalizado para certas entidades em termos de controle de acesso então eu escrevi o seguinte, ele procura por um método mais adequado para a questão usando System.Reflection, "pode ??esta entidade ser escrito por este usuário?"

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

Agora, cada vez que adicionar ou remover um método, eu só tenho para adicionar ou removê-lo em um lugar

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top