Existe uma maneira de forçar uma classe C # para implementar determinadas funções estáticas?

StackOverflow https://stackoverflow.com/questions/577749

Pergunta

Estou desenvolvendo um conjunto de classes que implementar uma interface comum . Um consumidor de minha biblioteca deve esperar que cada uma dessas classes para implementar um determinado conjunto de funções estáticas. Existe uma maneira que eu posso decorar estes classe para que o compilador vai pegar o caso em que uma das funções não é implementada.

Eu sei que acabará por ser capturado durante a criação do código de consumir. E eu também sei como contornar esse problema usando um tipo de classe de fábrica.

Apenas curioso para saber se há alguma sintaxe / atributos lá fora, para exigir funções estáticas em uma classe.

Ed Removido a palavra 'interface' confusão evitar.

Foi útil?

Solução

Não, não há suporte de idioma para isso em C #. Há duas soluções que eu posso pensar de imediato:

  • uso reflexão em tempo de execução; os dedos cruzados e esperança ...
  • usar um singleton / default instância / semelhante ao implementar uma interface que declara os métodos

( update )

Na verdade, desde que você tem teste de unidade, a primeira opção não é realmente tão ruim como se poderia pensar, se (como eu) você vem de um fundo "tipagem estática" rigorosa. O fato é que; ele funciona muito bem em linguagens dinâmicas. E, de fato, isso é exatamente como o meu operadores genéricos código funciona - it esperanças você tem os operadores estáticos. Em tempo de execução, se você não fizer isso, ele vai rir de você em um tom adequadamente zombando ... mas não pode verificar em tempo de compilação.

Outras dicas

No. Basicamente, parece que você está depois uma espécie de "polimorfismo estático". Isso não existe em C #, embora eu tenha sugerido uma espécie de "noção de interface estática", que poderia ser útil em termos de genéricos .

Uma coisa que você poderia fazer é escrever um teste de unidade simples para verificar que todos os tipos em um determinado conjunto de obedecer suas regras. Se outros desenvolvedores também implementará a interface, você poderia colocar esse código de teste em algum lugar comum para que todos implementar a interface pode facilmente testar suas próprias assembléias.

Esta é uma grande pergunta e uma que eu encontrei em meus projetos.

Algumas pessoas sustentam que as interfaces e classes abstratas existem para polimorfismo apenas, não para forçar tipos de implementar certos métodos. Pessoalmente, considero polimorfismo um caso de uso primário, e implementação forçou um secundário. Eu uso a técnica de implementação forçada com bastante frequência. Normalmente, ele aparece no código do framework implementação de um modelo padrão. A classe base / modelo encapsula uma idéia complexa, e subclasses fornecem inúmeras variações de implementar os métodos abstratos. Um benefício pragmática é que os métodos abstratos fornecer orientação para outros desenvolvedores de aplicação das subclasses. Visual Studio ainda tem a capacidade de stub os métodos para você. Isso é especialmente útil quando um desenvolvedor de manutenção necessidades para adicionar um novo meses subclasse ou anos mais tarde.

A desvantagem é que não há suporte específico para alguns destes cenários modelo em C #. Os métodos estáticos são um. Outra é construtores; idealmente, ISerializable deve forçar o desenvolvedor para implementar o construtor serialização protegido.

A abordagem mais fácil provavelmente é (como sugerido anteriormente) para usar um teste automatizado para verificar se o método estático é implementado nos tipos desejados. Outra idéia viável já mencionado é implementar uma regra de análise estática.

Uma terceira opção é usar uma estrutura de Programação Orientada a Aspectos como PostSharp . PostSharp suporta a validação em tempo de compilação de aspectos. Você pode escrever código .NET que reflete sobre o conjunto em tempo de compilação, gerando advertências arbitrárias e erros. Normalmente, você faz isso para validar que um uso aspecto é apropriado, mas eu não vejo por que você não poderia usá-lo para validar regras de modelo também.

Infelizmente, não, não há nada como este construído dentro da linguagem.

Enquanto não há suporte de idioma para isso, você pode usar uma ferramenta de análise estática para aplicá-la. Por exemplo, você pode escrever uma regra personalizada para FxCop que detecta uma implementação atributo ou interface em uma classe e, em seguida, verifica a existência de certos métodos estáticos.

O padrão Singleton não ajuda em todos os casos. Meu exemplo é de um projeto real da mina. Não é planejado.

Eu tenho uma classe (vamos chamá-lo "Widget") que herda de uma classe em um ORM de terceiros. Se eu instanciar um objeto Widget (portanto, a criação de uma linha no db) só para ter certeza de que meus métodos estáticos são declarados, eu estou fazendo uma bagunça maior do que o que eu estou tentando limpar.

Se eu criar esse objeto extra no armazenamento de dados, eu tenho que esconder isso de usuários, cálculos, etc.

I usar interfaces em C # para se certificar de que eu implementar características comuns em um conjunto de classes.

Alguns dos métodos que implementam estas funções exigem dados de instância para executar. código que estes métodos como métodos de instância, e usar uma interface C # para se certificar que existe na classe.

Alguns desses métodos não requerem dados de instância, por isso são métodos estáticos. Se eu pudesse declarar interfaces com métodos estáticos, o compilador pode verificar se existem ou não esses métodos na classe que diz que implementa a interface.

Não, não haveria nenhum ponto em este recurso. Interfaces são basicamente uma reduzida forma de herança múltipla. Eles dizer ao compilador como configurar a tabela de função virtual para que métodos virtuais não-estáticos podem ser chamados corretamente em classes descendentes. Os métodos estáticos não pode ser virtual, portanto, não há nenhum ponto na utilização de interfaces para eles.

A abordagem que você fica mais perto do que você precisa é um singleton, como Marc Gravell sugerido.

Interfaces, entre outras coisas, permitem que você fornecer algum nível de abstração para suas classes para que você possa usar uma determinada API, independentemente do tipo que implementa-lo. No entanto, desde que você precisa saber o tipo de uma classe estática para usá-lo, por que você deseja impor essa classe para implementar um conjunto de funções?

Talvez você poderia usar um atributo personalizado como [ImplementsXXXInterface] e proporcionar algum tempo de execução verificação para garantir que as classes com esse atributo realmente implementar a interface que você precisa?

Se você está apenas após a obtenção desses erros do compilador, considere esta configuração:

  1. Definir os métodos em uma interface.
  2. Declare os métodos com abstrato.
  3. Implementar os métodos estáticos públicos, e ter o método abstratas substituições simplesmente chamar os métodos estáticos.

É um pouco de código extra, mas você saberá quando alguém não está a implementar um método necessário.

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