Pergunta

OK, isso segue de minha pergunta anterior.

O que eu realmente gostaria de fazer é criar algum tipo de atributo que me permita decorar um método que irá quebrar a construção.Muito parecido com o Obsoleto("motivo", verdadeiro) atributo, mas sem identificar falsamente código obsoleto.

Esclarecer:Eu não quero que isso quebre a construção QUALQUER Pressione F6 (Build), só quero interromper a compilação se um método decorado com o atributo for chamado em algum outro lugar do código.Como eu disse, semelhante obsoleto, mas não o mesmo.

Eu sei que não estou sozinho nisso, pois outros usuários desejam usá-lo por outros motivos.Nunca criei atributos personalizados antes, então é tudo novo para mim!

Foi útil?

Solução

Se for para serialização XML e NHibernate, onde você deseja que o construtor sem parâmetros seja acessível (como é o caso no exemplo você referenciou), então use um construtor sem parâmetros privado ou protegido para serialização ou um construtor protegido para NHibernate.Com a versão protegida, você está se abrindo para que classes herdadas possam chamar esse código.

Se você não quiser que o código chame um método, não o torne acessível.

EDITAR:Talvez para responder à questão mais profunda, o compilador AFAIK conhece apenas três atributos: Obsoleto, condicional e uso de atributos.Adicionar tratamento especial para outros atributos exigiria a modificação do compilador.

Outras dicas

Acho que esta seria uma excelente solicitação de recurso para a Microsoft:Crie um atributo abstrato de classe base CompilerExecutedAttribute que o compilador processa de alguma maneira ou que pode influenciar o processo de compilação.Então poderíamos herdar deste atributo e implementar diferentes operações, por ex.emitir um erro ou um aviso.

Se você considerar um aviso (que é o que [Obsoleto] lança) como uma quebra de compilação, basta usar o #aviso diretiva do compilador.

Editar:Nunca usei, mas #erro também está disponível.

Acho que a única maneira infalível seria estender o Visual Studio (por meio de VSIP) e assinar o evento correto (talvez na classe EnvDTE.BuildEvents), verificar seu código para uso do construtor e cancelar a compilação se você detectá-lo.

Tudo isso está começando a soar um pouco como TDWTF de ontem. :-)

Terei que concordar com Greg:crie um atributo para ele.

E se você estiver realmente falando sério, talvez encontre uma maneira de descobrir se o construtor está sendo acessado por algo diferente de XMLSerializer e lançar uma exceção, se estiver.

Eu sugiro que você use a diretiva #error.

Outro atributo bastante desconhecido que pode fazer o trabalho é o atributo condicional (dependendo do que você está tentando alcançar)

[Conditional("CONDITION")] 
public static void MiMethod(int a, string msg)

que removerá a invocação do método do próprio código IL se "MY_CONDITION" for definido.

Crie uma regra FxCop e adicione FxCop à sua construção de integração para verificar isso.

Você receberá avisos, em vez de uma compilação com falha.Os atributos são executados no momento da reflexão, e não no momento da construção.

Alternativamente (e isso é bastante desagradável) coloque uma diretiva do compilador em torno do método que você não deseja que seja chamado.Então seu código será quebrado se você chamá-lo, mas você pode configurar uma compilação que passe a diretiva correta do compilador e não o faça.

Lançar uma exceção personalizada e um teste de unidade como uma etapa pós-construção

Respondendo 4 anos depois :)

Eu tive a mesma pergunta se houvesse uma alternativa ao Obsoleto.

Pelo que me lembro (vídeos do canal 9), há pouco tempo, a Microsoft afirmou que está trabalhando para dar aos desenvolvedores acesso a algo como uma API de compilador em algum momento, então no futuro é concebível que você possa escrever um "plugin" de compilador que permitiria para decorar métodos com seu próprio atributo personalizado e dizer ao compilador para cancelar se parecer que o código decorado pode estar sendo chamado em algum outro lugar do código, etc.

O que seria realmente muito legal quando você pensa sobre isso.Isso também me lembra que eu também deveria tentar ler sobre o progresso daquela API do compilador em que a MS está trabalhando ...

Por que não inventar algo?Um atributo desconhecido certamente quebraria a construção.

[MyMadeUpAttributeThatBreaksTheBuildForSure]
public class NotDoneYet {}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top