Pergunta

Existem bons usos de classes parciais fora dos cenários de código gerados por webforms/winforms?Ou esse recurso é basicamente para oferecer suporte a isso?

Foi útil?

Solução

É em parte suportar cenários (WebForms, Winforms, Linq-to-SQL, etc), o código gerado com código de programador.

Há mais razões para usá -lo. Por exemplo, se você tiver grandes classes em arquivos grandes e pesados, mas as classes têm grupos de métodos logicamente relacionados, classes parciais podem ser uma opção para tornar seus tamanhos de arquivo mais gerenciáveis.

Outras dicas

A geração de código foi a força motriz por trás das classes parciais. A necessidade vem de ter uma classe gerada por código que está mudando constantemente, mas permite que os desenvolvedores forneçam código personalizado como parte da classe que não será substituída toda vez que forem feitas alterações que forçam a classe a ser regenerada.

Veja WinForms ou Datasets digitados, por exemplo (ou qualquer designer para esse assunto). Toda vez que você faz uma alteração no designer, ela serializa o código correspondente em um arquivo. Digamos que você precise fornecer alguns métodos adicionais sobre os quais o gerador não sabe nada. Se você o adicionou ao arquivo gerado, suas alterações serão perdidas na próxima vez que ele foi gerado.

Um projeto em que estou trabalhando atualmente usa a geração de código para todas as entidades DAL, BLL e negócios. No entanto, o gerador obtém apenas 75% das informações. A parte restante deve ser codificada à mão (lógica de negócios personalizada, por exemplo). Posso assumir que toda classe BLL possui um método selecionado, para que seja fácil de gerar. No entanto, meu cliente BLL também precisa ter um método SelectAllByLocation. Não posso colocar isso no meu gerador porque não é genérico para todas as classes BLL. Portanto, gero todas as minhas classes como classes parciais e, em um arquivo separado, defino meus métodos personalizados. Agora, no futuro, quando minha estrutura mudar, ou eu preciso regenerar meu BLL por algum motivo, meu código personalizado não será eliminado.

Eu uso classes parciais como um meio de separar os diferentes submetidos dos controles personalizados que escrevo. Além disso, quando usado com o software de criação de entidades, permite que produtos como o LLBLGEN criem versões geradas de classes, bem como uma versão personalizada e editada pelo usuário, que não serão substituídas se as entidades precisarem ser regeneradas.

Costumo usar classes parciais para dar a cada classe aninhada seu próprio arquivo. Houve algumas arquiteturas em que trabalhei onde a maior parte da implementação era exigida apenas por uma classe e, portanto, aninhamos essas classes nessa classe. Fazia sentido manter os arquivos mais fáceis de manter usando a capacidade de classe parcial e dividindo cada um em seu próprio arquivo.

Também os usamos para agrupar as substituições de ações ou o esconderijo de um conjunto de propriedades. Coisas assim. É uma maneira útil de misturar uma mudança de estoque (basta copiar o arquivo e alterar o nome da classe parcial para a classe de destino - desde que a classe de destino também seja parcial, é claro).

Outro uso possível para classes parciais seria aproveitar os métodos parciais para fazer métodos desaparecer seletivamente usando a compilação condicional - isso seria ótimo para o código de diagnóstico de modo de depuração ou cenários de testes de unidade especializados.

Você pode declarar um método parcial como um método abstrato e, na outra classe parcial, quando você digita a palavra -chave "parcial", pode aproveitar o IntelliSense para criar a implementação desse método.

Se você cercar uma parte com declarações de construção condicional, poderá cortar facilmente o código apenas de depuração ou teste. No exemplo abaixo, no modo de depuração, o método logsomethingdebugonly é chamado, mas na construção de liberação, é como se o método não existisse - uma boa maneira de manter o código de diagnóstico longe do código de produção sem um monte de ramificação ou Múltiplos blocos de compilação condicional.

// Main Part
public partial class Class1
{
    private partial void LogSomethingDebugOnly();

    public void SomeMethod()
    {
        LogSomethingDebugOnly();
        // do the real work
    }
}

// Debug Part - probably in a different file
public partial class Class1
{

    #if DEBUG

    private partial void LogSomethingDebugOnly()
    {
        // Do the logging or diagnostic work
    }

    #endif
}

O LINQ para SQL faz bom uso de classes parciais para estender o código gerado pelo designer. Eu acho que você normalmente encontrará esse padrão de classes parciais sendo usadas pelo código criado por designers.

Acho que aulas parciais são extremamente úteis.Geralmente eles são usados ​​para estender classes geradas automaticamente.Eu os usei em um projeto com testes de unidade pesados.Minhas classes UT tinham dependências complexas e não era muito prático separar o código em várias classes. É claro que é melhor usar herança\composição, mas em alguns casos classes parciais podem ser muito úteis.

Como mencionado anteriormente, eu também acho que esse é um cheiro de código.

Se uma classe é tão grande que precisa ser dividida em mais arquivos, significa que está quebrando o princípio de responsabilidade única e fazendo muitas coisas. A classe grande pode ser dividida em classes menores que cooperam juntas.

Se você precisar usar classes ou regiões parciais para organizar o código, considere se elas devem estar em suas próprias classes. Aumenta a legibilidade e você obterá mais reutilização de código.

Talvez seja tarde demais, mas por favor, deixe -me adicionar meus 2 centavos também:

*. Ao trabalhar em grandes projetos, a divulgação de uma classe em arquivos separados permite que vários programadores funcionem simultaneamente.

*. Você pode escrever facilmente seu código (para funcionalidade estendida) para uma classe gerada por vs.net. Isso permitirá que você escreva o código de sua própria necessidade sem mexer com o código gerado pelo sistema

Where I'm at we have a program that handles incoming files from clients. It's set up so that each client's code is in it's own class library project, which knows how to handle whatever format that client chooses to use.

The main code uses the libraries by defining a fairly extensive interface that a class in the library must implement (probably should be a few distinct interfaces, but it's too late to change it now). Sometimes that involves a lot more code in the same class than we'd normally think prudent. Partial classes allow us to break them up somewhat.

On UserControls which are relatively complicated, I put the event handling stuff in one file and the painting and properties in another file. Partial classes work great for this, Usually these parts of the class are relatively independent and it's nice to be able to edit painting and event handling side by side.

I worked on a project a couple years ago where we had a typed DataSet class that had a ton of code in it: Methods in the DataTables, methods in the TableAdapters, declarations of TableAdapter instances, you name it. It was a massive central point of the project that everyone had to work on often, and there was a lot of source-control contention over the partial class code file.

So I split the code file into fix or six partial class files, grouped by function, so that we could work on smaller pieces and not have to lock the whole file every time we had to change some little thing.

(Of course, we could also have solved the problem by not using an exclusively-locking source-control system, but that's another issue.)

Generally, I consider it a code smell.

If your class is that complicated then it can probably be broken up into smaller reusable components.

Or it means that theres no inheritance hierarchy where there should be one.

For code generation scenarios it's good but I think code generation is another code smell.

I am late in the game... but just my 2 cents...

One use could be to refactor an existing god class in an existing legacy code base to multiple partial classes. It could improve the discoverability of code - if proper naming convention is being followed for the file names containing the partial classes. This could also reduce the source code repository - resolve and merge to an extent.

Ideally, a god class should be broken down into multiple small classes - each having single responsibility. Sometimes it is disruptive to perform medium to large refactorings. In such cases partial classes could provide a temporary relief.

Correction, as Matt pointed out, both sides of the partial need to be in the same assembly. my bad.

I use it in a data access layer. The generated classes like the mapper and queries a partial. If I need to add a mapper method for example to do a fancy load that's not generated I add it to the custom class.

At the end the programmer that uses the data layer in the business layer only sees one class with all the functionality he or she needs. And if the data source changes the generic parts can easily be generated without overwriting custom stuff.

I just found a use for partial classes. I have a [DataContract] class that I use to pass data to the client. I wanted the client to be able to display the class in a specific way (text output). so I created a partial class and overrode the ToString method.

Sometimes you might find terribly old code at work that may make it close to impossible to refactor out into distinct elements without breaking existing code.

When you aren't given the option or the time to create a more genuine architecture, partial classes make it incredibly easy to separate logic where its needed. This allows existing code to continue using the same architecture while you gain a step closer to a more concrete architecture.

Anywhere you'd have used #region sections before probably makes more sense as separate files in partial classes.

I personally use partial classes for large classes where static members go in one file and instance members go in the other one.

EDIT: DSL Tools for Visual Studio uses partial classes.

Thus, it's a feature that many automatic generated code uses. Instead of using #region the automatic generated code goes to one file and the user code (also called custom code) goes to another and even in different directories so that the developer does not get confused with so many meaningless files.

It's good to have this choice which you can combine - but not forced to use -with inheritance

Also, it can be handy to separate the logic of some classes among several directories. Of course, for machines, it's the same, but it enhances the user readability experience.

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