Quando è appropriato usare le classi parziali C #?


Risposte:


423

Il più grande uso di classi parziali è di rendere la vita più facile per i generatori / progettisti di codice. Le classi parziali consentono al generatore di emettere semplicemente il codice che devono emettere e non devono gestire le modifiche dell'utente al file. Allo stesso modo, gli utenti sono liberi di annotare la classe con i nuovi membri disponendo di una seconda classe parziale. Ciò fornisce un quadro molto pulito per la separazione delle preoccupazioni.

Un modo migliore per vederlo è vedere come funzionavano i designer prima delle lezioni parziali. Il designer di WinForms avrebbe sputato tutto il codice all'interno di una regione con commenti fortemente formulati sulla non modifica del codice. Doveva inserire ogni sorta di euristica per trovare il codice generato per successive elaborazioni. Ora può semplicemente aprire il file designer.cs e avere un alto grado di sicurezza che contiene solo codice rilevante per il designer.


70
Tentato di darti -1 per avermi fatto incubi su quanto erano brutte le cose prima delle lezioni parziali :)
Jon B

9
@Jon :), penso che abbiamo avuto tutti quegli incubi.
JaredPar,

18
Una volta ho scritto un generatore di codice che produce più di 36K righe (o probabilmente molto di più, non ricordo esattamente) e i miei editor sono stati bloccati quando è stata aperta la fonte. Le classi parziali mi hanno permesso di vedere il codice prodotto senza avere 4 GB di RAM.
Luca,

6
Direi che questo è l'unico uso per le classi parziali nel codice di produzione. Anche se accetto, può essere utile per il refactoring.
Gordon McAllister,

5
@Gordon - La risposta di HumerGu è un'altra su cui credo sia abbastanza difficile discutere. Le classi parziali possono essere molto utili per l'implementazione delle interfacce in C # e per mantenere i membri dell'interfaccia chiaramente separati dai membri della classe: stackoverflow.com/questions/3601901/why-use-partial-classes/…
STW

262

Un altro uso è quello di dividere l'implementazione di diverse interfacce, ad esempio:

partial class MyClass : IF1, IF2, IF3
{
    // main implementation of MyClass
}


partial class MyClass
{
    // implementation of IF1
}

partial class MyClass
{
    // implementation of IF2
}

6
Buon punto! È qualcosa che ho fatto prima e dimenticato, ma è sicuramente un bel modo per rendere chiaramente visibili i membri dell'interfaccia (specialmente in C #, poiché VB.NET usa la Implementsparola chiave per indicare un metodo appartiene a un'interfaccia)
STW

2
punto molto bello, ciascuna interfaccia può essere implementata da uno sviluppatore, inoltre è un buon modo per trovare facilmente l'implementazione dell'interfaccia.
Kokabi,

3
come si fa a sapere quale è per IF1 o IF2 .. dall'ordine di dichiarazione delle classi?
Kuldeep,

17
Un buon uso ma un cattivo esempio. Perché oh perché dovresti definire tutte le interfacce su una classe parziale e implementare quelle stesse interfacce in altre classi parziali? ..
inkredibl

4
Ah, ho appena cercato questa domanda per vedere se separare le implementazioni dell'interfaccia era un uso standard per le classi parziali. Sono contento di vedere che gli altri lo vedono come una buona idea. Concordo con @inkredibl sul mettere insieme la definizione dell'interfaccia con la classe parziale che la implementa.
Kim,

172

A parte le altre risposte ...

Li ho trovati utili come trampolino di lancio nel refactoring delle classi divine. Se una classe ha più responsabilità (specialmente se si tratta di un file di codice molto grande), trovo utile aggiungere 1x classe di responsabilità parziale come primo passaggio per l'organizzazione e quindi il refactoring del codice.

Questo aiuta molto perché può aiutare a rendere il codice molto più leggibile senza effettivamente influenzare il comportamento di esecuzione. Può anche aiutare a identificare quando una responsabilità è facile da escludere o è strettamente aggrovigliata con altri aspetti.

Tuttavia - per essere chiari - questo è ancora un codice errato, alla fine dello sviluppo vuoi ancora una responsabilità per classe ( NON per classe parziale). È solo un trampolino di lancio :)


23
Molto bello: "... alla fine dello sviluppo vuoi ancora una responsabilità per classe ( NON per classe parziale) ..."
kokabi

Per me, non è un buon stile di codifica, ma può rendere i codici errati un aspetto migliore.
themefield

Sono pienamente d'accordo con questo. È un buon trampolino verso la correzione del codice errato. Una classe divina è un tempo di classe divina che si sviluppa su più file o meno.
Jimbo,

84
  1. Sviluppatore multiplo utilizza classi parziali lo sviluppatore multiplo può lavorare facilmente sulla stessa classe.
  2. Generatore di codice Le classi parziali vengono utilizzate principalmente dal generatore di codice per tenere separate le diverse preoccupazioni
  3. Metodi parziali Utilizzando le classi parziali è anche possibile definire metodi parziali, in cui uno sviluppatore può semplicemente definire il metodo e l'altro sviluppatore può implementarlo.
  4. Solo dichiarazione del metodo parziale Anche il codice viene compilato solo con la dichiarazione del metodo e se l'implementazione del metodo non è presente il compilatore può rimuovere in modo sicuro quel pezzo di codice e non si verificherà alcun errore di tempo di compilazione.

    Per verificare il punto 4. È sufficiente creare un progetto winform e includere questa riga dopo il costruttore Form1 e provare a compilare il codice

    partial void Ontest(string s);

Ecco alcuni punti da considerare durante l'implementazione delle classi parziali: -

  1. Usa una parola chiave parziale in ogni parte della classe parziale.
  2. Il nome di ciascuna parte della classe parziale dovrebbe essere lo stesso, ma il nome del file di origine per ciascuna parte della classe parziale può essere diverso.
  3. Tutte le parti di una classe parziale devono trovarsi nello stesso spazio dei nomi.
  4. Ogni parte di una classe parziale deve trovarsi nello stesso assembly o DLL, in altre parole non è possibile creare una classe parziale nei file di origine da un progetto di libreria di classi diverso.
  5. Ogni parte di una classe parziale deve avere la stessa accessibilità. (es .: privato, pubblico o protetto)
  6. Se erediti una classe o un'interfaccia su una classe parziale, questa viene ereditata da tutte le parti di quella classe parziale.
  7. Se una parte di una classe parziale viene sigillata, l'intera classe verrà sigillata.
  8. Se una parte della classe parziale è astratta, l'intera classe verrà considerata una classe astratta.

1
C'è qualche problema a modificare una classe parziale creata da Entity Framework? Vorrei cambiare alcuni nomi di classi, creati da una tabella.
MarceloBarbosa,

Ho le stesse preoccupazioni. Voglio conoscere i vantaggi "Se presenti" che una classe parziale ha quando costruisce modelli che Entity Framework utilizzerà essenzialmente per costruire il mio database da una prospettiva / approccio / implementazione di Code First ... che cosa hai.
Chef_Code

@JimBalter Esegui gentilmente questo link msdn.microsoft.com/en-us/library/6b0scde8(v=vs.110).aspx . Ciò indica che se non è presente alcuna implementazione, il compilatore rimuoverà il pezzo di codice e non verrà ricevuto alcun errore di tempo di compilazione.
hellowahab,

Se erediti una classe o un'interfaccia su una classe parziale, questa viene ereditata da tutte le parti di quella classe parziale.
Il pisello rosso

56

Un grande uso è la separazione del codice generato dal codice scritto a mano che appartiene alla stessa classe.

Ad esempio, poiché LINQ to SQL utilizza classi parziali, è possibile scrivere la propria implementazione di determinate funzionalità (come le relazioni Many-to-Many) e tali parti di codice personalizzato non verranno sovrascritte quando si rigenererà il codice.

Lo stesso vale per il codice WinForms. Tutto il codice generato da Designer si trova in un file che generalmente non tocchi. Il tuo codice scritto a mano va in un altro file. In questo modo, quando cambi qualcosa in Designer, le tue modifiche non vengono spazzate via.


21

È vero che la classe parziale viene utilizzata nella generazione automatica del codice, un uso può essere quello di mantenere un file di classe di grandi dimensioni che potrebbe avere migliaia di righe di codice. Non sai mai che la tua classe potrebbe finire con 10 mila righe e non vuoi creare una nuova classe con un nome diverso.

public partial class Product
{
    // 50 business logic embedded in methods and properties..
}

public partial class Product
{
    // another 50 business logic embedded in methods and properties..
}
//finally compile with product.class file.

Un altro possibile uso potrebbe essere che più di uno sviluppatore possa lavorare sulla stessa classe in quanto sono memorizzati in luoghi diversi. Le persone potrebbero ridere ma non sai mai che a volte può essere una manciata.

Product1.cs

public partial class Product
{
    //you are writing the business logic for fast moving product
}

Product2.cs

public partial class Product
{
    // Another developer writing some business logic...
}

Spero abbia senso!


13

Le classi parziali si estendono su più file.

Come puoi usare il modificatore parziale su una dichiarazione di classe C #?

Con le classi parziali, puoi separare fisicamente una classe in più file. Questo è spesso fatto dai generatori di codice.

Esempio

Con le normali classi C #, non è possibile dichiarare una classe in due file separati nello stesso progetto. Ma con il partialmodificatore, puoi.

Ciò è utile se un file viene comunemente modificato e l'altro è generato automaticamente o raramente modificato.

Ecco un esempio per chiarire:

class Program
{
    static void Main()
    {
        A.A1();
        A.A2();
    }
}

Contenuto del file A1.cs: C #

using System;

partial class A
{
    public static void A1()
    {
        Console.WriteLine("A1");
    }
}

Contenuto del file A2.cs: C #

using System;

partial class A
{
    public static void A2()
    {
        Console.WriteLine("A2");
    }
}

Produzione:

A1
A2

Parziale è richiesto qui.

Se rimuovi il partialmodificatore, otterrai un errore contenente questo testo:

[Lo spazio dei nomi ' <global namespace>' contiene già una definizione per ' A'].

Mancia:

Per risolvere questo problema, puoi utilizzare la partialparola chiave o modificare uno dei nomi delle classi.

In che modo il compilatore C # gestisce le classi parziali?

Se si disassembla il programma sopra (usando IL Disassembler), vedrai che i file A1.cs e A2.cs vengono eliminati. Scoprirai che è presente la classe A.

La classe A conterrà i metodi A1 e A2 nello stesso blocco di codice. Le due classi sono state unite in una.

Risultato compilato di A1.cs e A2.cs: C #

internal class A
{
    // Methods
    public static void A1()
    {
        Console.WriteLine("A1");
    }

    public static void A2()
    {
        Console.WriteLine("A2");
    }
}

Sommario

  • Le classi parziali possono semplificare determinate situazioni di programmazione C #.
  • Vengono spesso utilizzati in Visual Studio durante la creazione di programmi Windows Form / WPF.
  • Il codice C # generato dalla macchina è separato.
  • Oppure puoi trovare l'intera descrizione qui .

2
Bell'esempio e ben documentato.
Chef_Code

1
Questa è la spiegazione più semplice da seguire imo.
Yusha,

12

mantieni tutto il più pulito possibile quando lavori con grandi classi o quando lavori in gruppo, puoi modificare senza ignorare (o sempre apportare modifiche)


11

L'uso principale per le classi parziali è con il codice generato. Se osservi la rete WPF (Windows Presentation Foundation), definisci l'interfaccia utente con markup (XML). Tale markup è compilato in classi parziali. Compila il codice con classi parziali tue.


8

Se hai una classe sufficientemente ampia che non si presta a un refactoring efficace, separarla in più file aiuta a mantenere le cose organizzate.

Ad esempio, se si dispone di un database per un sito contenente un forum di discussione e un sistema di prodotti e non si desidera creare due classi di provider diversi (NON la stessa cosa di una classe proxy, solo per essere chiari), è possibile creare una singola classe parziale in diversi file, come

MyProvider.cs - logica di base

MyProvider.Forum.cs - metodi specifici per il forum

MyProvider.Product.cs - metodi per i prodotti

È solo un altro modo per organizzare le cose.

Inoltre, come altri hanno già detto, si tratta dell'unico modo per aggiungere metodi a una classe generata senza correre il rischio che le aggiunte vengano distrutte alla successiva rigenerazione della classe. Questo è utile con codice generato dal modello (T4), ORM, ecc.


2
Vorrei sostenere il parziale come un trampolino di lancio verso il refactoring (l'intero punto della mia risposta), ma non li suggerirei come una soluzione effettiva per scrivere codice pulito. Se una classe parziale è nettamente separata dalle altre preoccupazioni della classe, allora perché non fare lo sforzo extra piccolo per promuoverla a una classe autonoma?
STW,

@STW: è possibile che molte istanze di oggetti vengano create e utilizzate per varie attività. Separare le varie attività in classi diverse richiederebbe di rintracciare quali istanze sono state usate per quali attività - potenzialmente un'impresa molto più grande del semplice spostamento di blocchi di codice tra i moduli sorgente.
supercat

4
@supercat - ho capito tutto, ma ripulire quel tipo di spaghetti dovrebbero essere intraprese. Ho un sacco di cicatrici da ripulire esattamente quel tipo di codice e non consiglierei mai di lasciarlo alle spalle. Questi tipi di pasticci sono garantiti per creare continuamente problemi e il payoff a lungo termine è enorme rispetto al semplice ignorare il problema. Un codice del genere non "odora", puzza come una discarica.
STW,

1
@supercat - Ho provato a qualificarlo con "Se un parziale è nettamente separato da altre preoccupazioni ... allora è un piccolo sforzo". Passare attraverso il dolore di districare di solito risparmierà molto nella manutenzione a lungo termine, se non Rogaine
STW

2
Per inciso, sto giocando con il tentativo di modificare Roslyn in questi giorni, ed è scritto con ampio uso di classi parziali. Molte e molte delle principali classi di Roslyn sono definite come classi parziali in più file. E Roslyn è stato scritto da persone che, almeno, considero programmatori C # molto intelligenti.
RenniePet,

8

In alternativa alle direttive pre-compilatore.

Se usi le direttive pre-compilatore (vale a dire #IF DEBUG), finisci con un codice dall'aspetto nodoso mescolato al tuo attuale codice di rilascio.

È possibile creare una classe parziale separata per contenere questo codice e racchiudere l'intera classe parziale in una direttiva oppure omettere tale file di codice dall'invio al compilatore (facendo effettivamente lo stesso).


Monogame utilizza questa strategia.
Zamboni,

6

I riferimenti di servizio sono un altro esempio in cui le classi parziali sono utili per separare il codice generato dal codice creato dall'utente.

È possibile "estendere" le classi di servizio senza sovrascriverle quando si aggiorna il riferimento del servizio.


6

Un altro uso che ho visto è

Estensione di una grande classe astratta per quanto riguarda la logica di accesso ai dati,

ho vari file con nomi Post.cs, Comment.cs, Pages.cs ...

in Post.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of post..
}


in Comment.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of comment..
}

in Pages.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of Pages..
}

6

Molte persone osservano che partialdovrebbe essere usato solo per una classe che ha un file di codice generato o per le interfacce. Non sono d'accordo, ed ecco il perché.

Per un esempio, diamo un'occhiata alla classe System.Math di C # ... questa è la classe . Non tenterei di inserire più di 70 metodi nello stesso file a codice singolo. Sarebbe un incubo da mantenere.

Posizionare ogni metodo matematico in singoli file di classe parziali e tutti i file di codice in una cartella Math nel progetto sarebbe un'organizzazione molto più pulita.

Lo stesso potrebbe / sarebbe vero per molte altre classi che hanno una grande quantità di funzionalità diverse. Ad esempio, una classe per la gestione dell'API PrivateProfile potrebbe trarre vantaggio dalla suddivisione in un set pulito di file di classi parziali in una singola cartella di progetto.

Personalmente, ho anche diviso ciò che la maggior parte delle persone chiama classi "helper" o "utility" in singoli file parziali per ciascun metodo o gruppo funzionale di metodo. Ad esempio, in un progetto la classe helper di stringa ha quasi 50 metodi. Sarebbe un file di codice lungo e ingombrante anche usando le regioni. È significativamente più facile da mantenere utilizzando singoli file di classe parziale per ciascun metodo.

Starei solo attento usando le classi parziali e manterrei coerente tutto il layout del file di codice durante il progetto. Ad esempio, inserendo qualsiasi enumerazione pubblica di classe e membri di classe privati ​​in un file Common.cs o con un nome simile nella cartella, anziché distribuirli sui file a meno che non siano specifici solo del file parziale in cui sono contenuti.

Tieni presente che quando dividi una classe in file separati perdi anche la possibilità di utilizzare la barra di divisione dell'editor di testo che ti consente di visualizzare contemporaneamente due diverse sezioni di un file corrente.


4

Le classi parziali consentono di aggiungere funzionalità a un programma adeguatamente progettato semplicemente aggiungendo file di origine. Ad esempio, è possibile progettare un programma di importazione di file in modo da poter aggiungere diversi tipi di file noti aggiungendo moduli che li gestiscono. Ad esempio, il convertitore del tipo di file principale potrebbe includere una piccola classe:

Classe pubblica parziale zzFileConverterRegistrar
    Registro eventi (ByVal mainConverter come zzFileConverter)
    Sottoregistratore Tutti (ByVal mainConverter as zzFileConverter)
        RaiseEvent Register (mainConverter)
    End Sub
End Class

Ogni modulo che desidera registrare uno o più tipi di convertitore di file potrebbe includere qualcosa come:

Classe pubblica parziale zzFileConverterRegistrar
    Private Sub RegisterGif (ByVal mainConverter as zzFileConverter) Gestisce Me.Register
        mainConverter.RegisterConverter ("GIF", GifConverter.NewFactory))
    End Sub
End Class

Si noti che la classe principale del convertitore di file non è "esposta", ma espone solo una piccola classe di stub a cui i moduli aggiuntivi possono agganciarsi. Esiste un leggero rischio di conflitti di denominazione, ma se la routine di "registrazione" di ciascun modulo aggiuntivo viene denominata in base al tipo di file che gestisce, probabilmente non dovrebbero costituire un problema. Uno potrebbe attaccare un GUID nel nome della subroutine di registrazione se fosse preoccupato per tali cose.

Modifica / Addendum Per essere chiari, lo scopo è quello di fornire un mezzo attraverso il quale una varietà di classi separate possono far conoscere un programma principale o una classe. L'unica cosa che farà il convertitore di file principale con zzFileConverterRegistrar è crearne un'istanza e chiamare il metodo registerAll che genererà l'evento Register. Qualsiasi modulo che vuole agganciare quell'evento può eseguire un codice arbitrario in risposta ad esso (questa è l'intera idea) ma non c'è niente che un modulo possa fare estendendo in modo improprio la classe zzFileConverterRegistrar se non definire un metodo il cui nome corrisponde a quello di qualcos'altro . Sarebbe certamente possibile per un'estensione scritta in modo improprio rompere un'altra estensione scritta in modo improprio, ma la soluzione è che chiunque non desideri che l'estensione venga semplicemente scritta correttamente.

Uno, senza usare le classi parziali, potrebbe avere un po 'di codice da qualche parte all'interno della classe principale del convertitore di file, che assomiglia a:

  RegisterConverter ("GIF", GifConvertor.NewFactory)
  RegisterConverter ("BMP", BmpConvertor.NewFactory)
  RegisterConverter ("JPEG", JpegConvertor.NewFactory)

ma aggiungere un altro modulo convertitore richiederebbe di entrare in quella parte del codice del convertitore e aggiungere il nuovo convertitore all'elenco. L'uso di metodi parziali non è più necessario: tutti i convertitori verranno inclusi automaticamente.


funziona, ma un semplice sistema di plugin per caricare dinamicamente questi moduli sarebbe molto più bello e aiuterebbe ad eliminare il rischio che i moduli si corrompano l'un l'altro (potrebbe caricare i moduli in fase di esecuzione anziché richiedere una ricompilazione)
STW

Il rischio che i moduli si corrompano l'un l'altro può essere ridotto al minimo se non fanno nulla con la classe zz_ se non agganciare un evento Register e chiamare una routine per registrarsi. Quali rischi vedi che non esisterebbero con un plug-in? I plug-in sono ottimi se l'utente finale deve "collegare" nuovi moduli. A volte, però, si vuole mettere tutte le funzionalità in un singolo exe. Essere in grado di collegare i file di origine senza dover aggiungere manualmente un riferimento ai file appena aggiunti può essere utile.
supercat

1
il rischio è abbastanza ben contenuto nella tua linea "... se non fanno nulla [...] tranne ...", la sicurezza e la stabilità ricadono interamente sullo sviluppatore a seguito della convenzione e forniscono una garanzia dello 0%. Se il tuo caso d'uso è di averli compilati (perfettamente validi, deve solo essere un compromesso di coscienza), allora perché non avere i moduli definiti in classi separate e implementare qualche IModuleinterfaccia?
STW,

Sembra un caso di "furbo" andato male. Questi non sono "moduli", sono una singola classe con molti comportamenti e responsabilità raggruppati in uno al momento della compilazione. Ci sono molti modi migliori per farlo - potresti usare Reflection per scansionare l'assembly compilato alla ricerca di classi che implementano IModule, puoi usare un framework di plugin come MEF (solo uno dei tanti), ecc. Ecc.
STW

3

Recentemente classi parziali hanno aiutato con il controllo del codice sorgente in cui più sviluppatori stavano aggiungendo a un file in cui venivano aggiunti nuovi metodi nella stessa parte del file (automatizzata da Resharper).

Queste spinte a git hanno causato conflitti di unione. Non ho trovato alcun modo per dire allo strumento di unione di prendere i nuovi metodi come blocco di codice completo.

Classi parziali a questo proposito consentono agli sviluppatori di attenersi a una versione del loro file e possiamo ricollegarli manualmente in seguito.

esempio -

  • MainClass.cs - contiene campi, costruttore, ecc
  • MainClass1.cs - un nuovo codice per gli sviluppatori mentre implementano
  • MainClass2.cs - è un'altra classe di sviluppatori per il loro nuovo codice.

3

Da MSDN :

1.In fase di compilazione, gli attributi delle definizioni di tipo parziale vengono uniti. Ad esempio, considerare le seguenti dichiarazioni:

[SerializableAttribute]
partial class Moon { }

[ObsoleteAttribute]
partial class Moon { }

Sono equivalenti alle seguenti dichiarazioni:

[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }

Di seguito vengono unite da tutte le definizioni di tipo parziale:

  • Commenti XML

  • interfacce

  • attributi di parametro di tipo generico

  • attributi di classe

  • membri

2. Un'altra cosa, le classi parziali nidificate possono anche essere parziali:

partial class ClassWithNestedClass
{
    partial class NestedClass { }
}

partial class ClassWithNestedClass
{
    partial class NestedClass { }
}

1

Ecco un elenco di alcuni dei vantaggi delle classi parziali.

È possibile separare il codice di progettazione dell'interfaccia utente e il codice della logica aziendale in modo che sia facile da leggere e comprendere. Ad esempio, stai sviluppando un'applicazione Web utilizzando Visual Studio e aggiungi un nuovo modulo Web, quindi ci sono due file di origine, "aspx.cs" e "aspx.designer.cs". Questi due file hanno la stessa classe con la parola chiave parziale. La classe ".aspx.cs" ha il codice della logica aziendale mentre "aspx.designer.cs" ha la definizione del controllo dell'interfaccia utente.

Quando si lavora con l'origine generata automaticamente, è possibile aggiungere il codice alla classe senza dover ricreare il file di origine. Ad esempio, stai lavorando con LINQ to SQL e crei un file DBML. Ora quando trascini e rilasci una tabella crea una classe parziale in designer.cs e tutte le colonne della tabella hanno proprietà nella classe. Sono necessarie più colonne in questa tabella per eseguire il bind sulla griglia dell'interfaccia utente ma non si desidera aggiungere una nuova colonna alla tabella del database in modo da poter creare un file di origine separato per questa classe che abbia una nuova proprietà per quella colonna e essere una classe parziale. Ciò influisce sul mapping tra la tabella del database e l'entità DBML, ma è possibile ottenere facilmente un campo aggiuntivo. Significa che puoi scrivere il codice da solo senza fare confusione con il codice generato dal sistema.

Più di uno sviluppatore può scrivere contemporaneamente il codice per la classe.

È possibile gestire meglio l'applicazione compattando classi di grandi dimensioni. Supponiamo di avere una classe con più interfacce in modo da poter creare più file di origine in base agli strumenti dell'interfaccia. È facile capire e mantenere un'interfaccia implementata su cui il file sorgente ha una classe parziale.


1

Ogni volta che ho una classe che contiene una classe nidificata di qualsiasi dimensione / complessità significativa, segnare la classe come partiale inserisco la classe nidificata in un file separato. Nomino il file contenente la classe nidificata usando la regola: [nome classe]. [Nome classe nidificata] .cs.

Il seguente blog MSDN spiega come utilizzare le classi parziali con le classi nidificate per la manutenibilità: http://blogs.msdn.com/b/marcelolr/archive/2009/04/13/using-partial-classes-with-nested-classes-for- maintainability.aspx


1

So che questa domanda è davvero vecchia, ma vorrei solo aggiungere il mio giudizio sulle lezioni parziali.

Uno dei motivi per cui utilizzo personalmente le classi parziali è quando creo i collegamenti per un programma, in particolare le macchine a stati.

Ad esempio, OpenGL è una macchina a stati, ci sono un sacco di metodi che possono essere tutti cambiati a livello globale, tuttavia, nella mia esperienza, legando qualcosa di simile a OpenGL in cui ci sono così tanti metodi, la classe può facilmente superare 10k LOC.

Le lezioni parziali lo analizzeranno per me e mi aiuteranno a trovare rapidamente i metodi.


0

Le classi parziali vengono introdotte principalmente per aiutare i generatori di codice, quindi noi (utenti) non finiamo per perdere tutto il nostro lavoro / modifiche alle classi generate come la classe .designer.cs di ASP.NET ogni volta che ci rigeneriamo, quasi tutti i nuovi strumenti che generano codice LINQ, EntityFrameworks, ASP.NET utilizzano classi parziali per il codice generato, quindi possiamo aggiungere o alterare in sicurezza la logica di questi codici generati sfruttando le classi e i metodi parziali, ma prestando molta attenzione prima di aggiungere elementi al codice generato usando le classi parziali è più semplice se rompiamo la build, ma peggio se introduciamo errori di runtime. Per ulteriori dettagli, consultare questo http://www.4guysfromrolla.com/articles/071509-1.aspx


0

Prendo atto di due usi che non sono riuscito a trovare esplicitamente nelle risposte.

Raggruppamento di articoli di classe

Alcuni sviluppatori usano i commenti per separare diverse "parti" della loro classe. Ad esempio, un team potrebbe utilizzare la seguente convenzione:

public class MyClass{  
  //Member variables
  //Constructors
  //Properties
  //Methods
}

Con le classi parziali, possiamo fare un passo ulteriore e dividere le sezioni in file separati. Come convenzione, una squadra potrebbe aggiungere un suffisso a ciascun file con la sezione corrispondente ad esso. Quindi in quanto sopra avremmo qualcosa di simile: MyClassMembers.cs, MyClassConstructors.cs, MyClassProperties.cs, MyClassMethods.cs.

Come è stato accennato ad altre risposte, se vale la pena dividere la classe o meno dipende probabilmente da quanto è grande la classe in questo caso. Se è piccolo, probabilmente è più facile avere tutto in una master class. Ma se una di quelle sezioni diventa troppo grande, il suo contenuto può essere spostato in una classe parziale separata, al fine di mantenere la classe principale in ordine. Una convenzione in tal caso potrebbe essere quella di lasciare un commento dicendo qualcosa come "Vedi classe parziale" dopo l'intestazione della sezione, ad esempio:

//Methods - See partial class

Gestione dell'ambito di utilizzo delle istruzioni / spazio dei nomi

Questo è probabilmente un evento raro, ma potrebbe esserci una collisione dello spazio dei nomi tra due funzioni delle librerie che si desidera utilizzare. In una singola classe, potresti utilizzare al massimo una clausola using per una di queste. Per l'altro avresti bisogno di un nome completo o di un alias. Con le classi parziali, poiché ogni spazio dei nomi e l'utilizzo dell'elenco delle istruzioni è diverso, si potrebbero separare i due insiemi di funzioni in due file separati.


Esistono meccanismi per risolvere la collisione dello spazio dei nomi, ad esempio rinominando uno spazio dei nomi usando using Library1 = The.Namespace.You.Needoglobal::Root.Of.Namespace
fjch1997

Sì, suppongo che sia un caso d'uso debole. Ma è un po 'più bello non dover qualificare completamente i nomi. Più di un piacevole effetto collaterale non intenzionale che un motivo per l'utilizzo di classi parziali.
Colm Bhandal,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.