Eu esperava fazer algo assim, mas parece ser ilegal em C #:
public Collection MethodThatFetchesSomething<T>()
where T : SomeBaseClass
{
return T.StaticMethodOnSomeBaseClassThatReturnsCollection();
}
Recebo um erro em tempo de compilação: "'T' é um 'parâmetro de tipo', que não é válido no contexto fornecido."
Dado um parâmetro de tipo genérico, como posso chamar um método estático na classe genérica? O método estático deve estar disponível, dada a restrição.
Respostas:
Nesse caso, você deve apenas chamar o método estático diretamente no tipo restrito. C # (e o CLR) não oferecem suporte a métodos estáticos virtuais. Assim:
... não pode ser diferente de:
Percorrer o parâmetro de tipo genérico é uma indireção desnecessária e, portanto, não é compatível.
fonte
return SomeBaseClass.StaticMethodOnSomeBaseClassThatReturnsCollection();
? Se sim, você pode querer adicionar isso à sua resposta. Obrigado. Funcionou para mim No meu caso, minha classe tinha um parâmetro de tipo, então eu fizreturn SomeBaseClass<T>.StaticMethodOnSomeBaseClassThatReturnsCollection();
e funcionou.Para elaborar uma resposta anterior, acho que reflexão está mais perto do que você quer aqui. Eu poderia dar 1001 razões pelas quais você deve ou não fazer algo, responderei sua pergunta conforme solicitado. Eu acho que você deve chamar o método GetMethod no tipo do parâmetro genérico e partir daí. Por exemplo, para uma função:
Onde T é qualquer classe que tenha o método estático fetchAll ().
Sim, estou ciente de que isso é terrivelmente lento e pode falhar se someParent não forçar todas as suas classes filhas a implementar fetchAll, mas responder à pergunta conforme solicitado.
fonte
A única maneira de chamar tal método seria por meio de reflexão. No entanto, parece que é possível envolver essa funcionalidade em uma interface e usar um padrão IoC / fábrica / etc baseado em instância.
fonte
Parece que você está tentando usar genéricos para contornar o fato de que não existem "métodos estáticos virtuais" em C #.
Infelizmente, isso não vai funcionar.
fonte
A partir de agora, você não pode. Você precisa de uma maneira de dizer ao compilador que T tem esse método e, atualmente, não há como fazer isso. (Muitos estão pressionando a Microsoft para expandir o que pode ser especificado em uma restrição genérica, então talvez isso seja possível no futuro).
fonte
Aqui, eu posto um exemplo que funciona, é uma solução alternativa
fonte
public T : SomeBaseClass
significa?Eu só queria dizer que às vezes os delegados resolvem esses problemas, dependendo do contexto.
Se você precisar chamar o método estático como algum tipo de fábrica ou método de inicialização, então você pode declarar um delegado e passar o método estático para a fábrica genérica relevante ou o que quer que precise dessa "classe genérica com este método estático".
Por exemplo:
Infelizmente, você não pode garantir que a classe tenha o método certo, mas pode pelo menos garantir que o método de fábrica resultante tenha tudo o que espera (ou seja, um método de inicialização com a assinatura correta). Isso é melhor do que uma exceção de reflexão de tempo de execução.
Essa abordagem também tem alguns benefícios, ou seja, você pode reutilizar métodos init, fazer com que sejam métodos de instância, etc.
fonte
Você deve ser capaz de fazer isso usando reflexão, conforme descrito aquiDevido ao link estar morto, encontrei os detalhes relevantes na máquina de retorno:
fonte