Pergunta

No Visual Studio 2008 usando C #, qual é a melhor maneira de compartilhar código em várias classes e arquivos de origem?

A herança não é a solução, como as classes já tem uma hierarquia significativa.

Existe alguma característica pura que é como um C arquivo de inclusão que lhe permite inserir código em qualquer lugar que você quer em uma outra classe?

EDIT:

ok, eu acho que nós precisamos de um exemplo concreto ...

Existem várias centenas de classes no domínio com uma hierarquia de classe bem pensado. Agora, muitas dessas classes precisam imprimir. Há uma classe de impressora utilitário que lida com a impressão. Vamos dizer que existem 3 métodos de impressão diferentes que são dependentes da classe que está sendo impresso. O código que chama o método de impressão (6 linhas) é o que eu estou tentando evitar copiando e colando em todas as diferentes páginas de classe cliente.

Seria bom se as pessoas não assumiria que sabiam mais sobre o domínio que o op - especialmente quando menciona especificamente técnicas que não se encaixam ...

Foi útil?

Solução

Se você tem funcionalidade que você usa com freqüência em classes que representam coisas muito diferentes, na minha experiência, que deve cair em apenas algumas categorias:

  • Utilities (por exemplo seqüência de formatação, análise, ...)
  • preocupações transversais (logging, aplicação de segurança, ...)

Para obter a funcionalidade do tipo utilitário que você deve considerar a criação de classes separadas, e referenciando as classes de utilitários quando necessário na classe executiva.

public class Validator
{
  public bool IsValidName(string name);
}

class Patient
{
  private Validator validator = new Validator();
  public string FirstName
  {
     set
     {
         if (validator.IsValidName(value)) ... else ...
     }
  }
}

Para preocupações transversais, tais como a exploração madeireira ou de segurança, sugiro que você investigue Programação Orientada a Aspectos .

Em relação ao printa vs. PrintB exemplo discutido em outros comentários, parece um excelente caso para o padrão de fábrica. É possível definir uma interface, por exemplo, IPrint, aulas printa e PrintB que tanto implementar IPrint, e atribuir uma instância de IPrint com base no que as necessidades determinada página.

// Simplified example to explain:

public interface IPrint 
{ 
   public void Print(string); 
}

public class PrintA : IPrint
{
   public void Print(string input)
   { ... format as desired for A ... }
}

public class PrintB : IPrint
{
   public void Print(string input)
   { ... format as desired for B ... }
}

class MyPage
{
   IPrint printer;

   public class MyPage(bool usePrintA)
   {
      if (usePrintA) printer = new PrintA(); else printer = new PrintB();
   }

   public PrintThePage()
   {
      printer.Print(thePageText);
   }
}

Outras dicas

Você não pode apenas carregar no código que você gostaria de ter adicionado a uma classe em C # através de um pré-processador diretiva como você faria em C.

Você poderia, no entanto, definir uma interface e extensão declarar métodos para essa interface. A interface pode então ser implementado por suas classes, e você pode chamar os métodos de extensão sobre essas classes. Por exemplo.

public interface IShareFunctionality { }

public static class Extensions
{
    public static bool DoSomething(this IShareFunctionality input)
    {
        return input == null;
    }
}

public class MyClass : Object, IShareFunctionality
{
    public void SomeMethod()
    {
        if(this.DoSomething())
            throw new Exception("Impossible!");
    }
}

Isso permitiria que você reutilize a funcionalidade, mas você não pode acessar os membros privados da classe como você seria capaz de se você poderia, por exemplo, mistura incluir um arquivo.

Podemos precisar alguns exemplos mais concretos do que você quer fazer então?

A classe C # utilitário irá trabalhar. Ele age como um registro central para o código comum (ou como a construção Módulo VB.NET) - ele deve conter código que não é específico para qualquer classe de outra forma que deveria ter sido anexado à classe relevante.

Você não quer começar a copiar o código-fonte ao redor se você não tem que, porque isso levaria a problemas de atualização do código considerando o duplicação .

Enquanto a fonte não precisa manter estado, em seguida, usar uma classe estática com método estático.

static public class MySharedMembers {
    static public string ConvertToInvariantCase(string str)  {
        //...logic
    }
    // .... other members
}

Se as classes estão no mesmo namespace, não há necessidade de um incluem analógico. Basta ligar para os membros da classe definida na outra função.

Se eles não estão no mesmo namespace, adicione o namespace das classes que pretende utilizar nas directivas usings e ele deve funcionar o mesmo que acima.

Eu estou confuso com a pergunta:. Parece que você precisa para trabalhar em sua compreensão básica OO

Eu não sei de uma maneira de incluir partes de arquivos, mas uma coisa que fazemos com freqüência é adicionar um arquivo existente e "link" de seu local atual. Por exemplo, temos um arquivo AssemblyInfo.cs que cada projeto refere-se a partir de um diretório solução. Nós alterá-lo uma vez e todos os projetos têm a mesma informação, porque eles estão referindo-se ao mesmo arquivo.

Caso contrário, sugestões sobre refatoração rotinas "comuns" em um common.dll são a melhor coisa que eu vim acima com em .Net.

Eu não tenho certeza exatamente o que você quer dizer com uma estrutura "significativa" já, mas isso soa como um lugar onde você poderia usar implementação de classe base. Embora não seja tão "detalhado" como herança múltipla C ++, você pode obter algum benefício fora de usar implementação da classe base acorrentado a reutilizar funções comuns.

Você pode preservar hierarquia de classes, pelo menos visualmente e comportamento de substituição, conforme necessário.

Retire o código repetitivo em serviços. O código repetitivo é um indício de que pode haver algum espaço para refatoração.

Por exemplo, criar um "PrintingService", que contém a lógica necessária para imprimir. Você pode então ter as classes que precisam imprimir tem uma dependência sobre este serviço (ou via o construtor ou um parâmetro em um método que requer o serviço).

Outra ponta i têm ao longo destas linhas é criar interfaces para a funcionalidade da base e, em seguida, utilizar as interfaces de código de encontro. Por exemplo, eu tinha monte de classes de relatórios que o usuário poderia ou fax, e-mail ou impressão. Em vez de criar métodos para cada um, eu criei um serviço para cada um, tinha-los a implementar uma interface que tinha um único método de saída (). Eu poderia, então, passar cada serviço para o mesmo método, dependendo do tipo de produto que o usuário queria. Quando o cliente queria usar eFax em vez de fax através do modem, que era apenas uma questão de escrever um novo serviço que implementou esta mesma interface.

Para ser honesto eu não consigo pensar em qualquer coisa como inclui no Visual C #, nem por que você quer esse recurso. Dito isto, as classes parciais pode fazer algo como isso soa o que você quer, mas usá-los talvez se choca contra o seu "classes já tem uma hierarquia significativa" exigência.

Você tem muitas opções, TT, método de extensão, delegar e lambda

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