Pergunta

Ok, eu sei o que você está pensando: "Por que escrever um método que você não quer que as pessoas usem?" Certo?

Bem, resumindo, tenho uma classe que precisa ser serializada para XML.Para que XmlSerializer para fazer sua mágica, a classe deve ter um construtor padrão vazio:

public class MyClass
{
  public MyClass()
  {
    // required for xml serialization
  }
}

Então, eu preciso disso, mas não quero que as pessoas tenham usar isso, então existe algum atributo que possa ser usado para marcar o método como "NÃO USE"?

Eu estava pensando em usar o Obsoleto atributo (já que isso pode interromper a construção), mas isso parece meio "errado", existe alguma outra maneira de fazer isso ou preciso ir em frente e morder a bala?:)

Atualizar

OK, aceitei a resposta de Keith, pois acho que do fundo do meu coração concordo totalmente.Foi por isso que fiz a pergunta em primeiro lugar: não gosto da ideia de ter o Obsoleto atributo.

No entanto...

é ainda é um problema, enquanto estamos sendo notificados no intellisense, idealmente, gostaríamos de quebrar a compilação, então existe alguma maneira de fazer isso?Talvez crie um atributo personalizado?

Uma pergunta mais focada foi criada aqui.

Foi útil?

Solução

Se uma aula for [Serialisable] (ou seja,ele pode ser copiado em qualquer lugar conforme necessário) o construtor sem parâmetros é necessário para desserializar.

Suponho que você queira forçar o acesso do seu código para passar padrões de suas propriedades para um construtor parametrizado.

Basicamente você está dizendo que está tudo bem para o XmlSerializer para fazer uma cópia e depois definir propriedades, mas você não quer que seu próprio código o faça.

Até certo ponto, acho que isso é um exagero.

Basta adicionar comentários XML que detalhem quais propriedades precisam ser inicializadas (e o que fazer).

Não use [Obsolete], porque não é.Reserve isso para métodos genuinamente obsoletos.

Outras dicas

Você pode usar:

[System.ComponentModel.EditorNavegável(System.ComponentModel.EditorBrowsableState.Never)]

para que não apareça no Intellisence.Se o consumidor ainda quiser usá-lo, ele poderá, mas não será tão detectável.

O ponto de Keith sobre o excesso de engenharia ainda permanece.

Li o título e pensei imediatamente em "atributo obsoleto".Que tal

    /// <summary>
    /// do not use
    /// </summary>
    /// <param name="item">don't pass it anything -- you shouldn't use it.</param>
    /// <returns>nothing - you shouldn't use it</returns>
    public bool Include(T item) { 
    ....

Na verdade, estaria inclinado a discordar de todos os que defendem a utilização do ObsoleteAttribute como a documentação do MSDN diz que:

Marcar um elemento como obsoleto informa aos usuários que o elemento será removido em versões futuras do produto.

Como os construtores genéricos para serialização XML não devem ser removidos do aplicativo, eu não os aplicaria apenas no caso de um desenvolvedor de manutenção no futuro não estar familiarizado com o funcionamento da serialização XML.

Na verdade, tenho usado Keith método de apenas observar que o construtor é usado para serialização na documentação XML para que apareça no Intellisense.

Você poderia construir o seu próprio Attribute classe derivada, digamos NonCallableAttribute para qualificar métodos e, em seguida, adicione à tarefa de análise de código de build/CI a verificação para monitorar se algum código está usando esses métodos.

Na minha opinião, você realmente não pode forçar os desenvolvedores a não usarem o método, mas pode detectar quando alguém quebrou a regra o mais rápido possível e consertar.

Uau, esse problema também está me incomodando.

Você também precisa de construtores padrão para o NHibernate, mas quero forçar as pessoas a NÃO usarem inicializadores de objeto C# 3.0 para que as classes passem pelo código do construtor.

throw new ISaidDoNotUseException();

Separe seu objeto serializável do seu objeto de domínio.

O que você está procurando é o ObsoleteAttribute aula:

using System;

public sealed class App {
   static void Main() {      
      // The line below causes the compiler to issue a warning:
      // 'App.SomeDeprecatedMethod()' is obsolete: 'Do not call this method.'
      SomeDeprecatedMethod();
   }

   // The method below is marked with the ObsoleteAttribute. 
   // Any code that attempts to call this method will get a warning.
   [Obsolete("Do not call this method.")]
   private static void SomeDeprecatedMethod() { }
}

ObsoleteAttribute provavelmente funcionará na sua situação - você pode até causar a quebra da compilação se esse método for usado.

Como os avisos obsoletos ocorrem em tempo de compilação e como a reflexão necessária para a serialização ocorre em tempo de execução, marcar esse método como obsoleto não interromperá a serialização, mas alertará os desenvolvedores de que o método não existe para ser usado.

estou usando o ObsoleteAttribute.

Mas você também pode fazer alguns comentários, é claro.

E finalmente remova-o completamente se puder (não precisa manter a compatibilidade com algo antigo).Essa é a melhor maneira.

Sim, existe.

Eu escrevi esta postagem no blog sobre isso Trabalhando com o designer.

E aqui está o código:


public class MyClass
{
  [Obsolete("reason", true)]
  public MyClass()
  {
    // required for xml serialization
  }
}

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