2010-11-30 39 views
8

Je veux mettre toutes les signatures des fonctions API Windows que j'utilise dans les programmes d'une classe, comme WinAPI, et dans un fichier WinAPI.cs que je vais inclure dans mes projets. La classe sera statique interne et les méthodes public static extern. (Quelque chose comme l'énorme NativeMethods.cs du code source .NET Framework).Grand fichier source C# avec les signatures, structures, constantes de la méthode API Windows: seront-ils tous inclus dans le fichier .exe final?

Disons que WinAPI.cs a une centaine de signatures méthodes natives comme:

[DllImport("user32.dll")] 
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 
  1. Si je vais seulement utiliser certains d'entre eux dans un projet (même un ou deux), si J'inclus le fichier WinAPI.cs dans mon projet, le .exe final sera-t-il rempli avec les déclarations de méthodes inutiles que je n'utilise pas (les 99 autres)? En ce qui concerne les déclarations de structure native, si je ne les utilise pas dans le projet en cours, seront-elles toujours incluses dans le fichier .exe final?

    [StructLayout(LayoutKind.Sequential)] 
        public struct POINT 
        { 
         public int X; 
         public int Y; 
        } 
    
  2. Qu'en déclarations constantes ou des membres readonly comme:

    public const int WH_JOURNALPLAYBACK = 1; 
    public static readonly int WM_GETTEXT = 0x0D; 
    

Répondre

2

Tous de ce seront inclus.Cependant, il sera inclus comme IL et quand le programme s'exécute c'est juste le code de machine compilé. Nous parlons peut-être 40K d'espace au maximum.

+0

Savez-vous pourquoi sont-ils tous inclus? C'est un cours interne, donc il ne devrait pas être référencé de l'extérieur. Pourquoi le compilateur C# ne peut-il pas voir les déclarations inutilisées et les supprimer simplement? – AnAurelian

+0

@David Parce que vous ne savez pas au moment de la compilation si elles seront utilisées ou non. Tout assembly (y compris les fichiers .exe) peut avoir besoin d'être référencé par un autre projet, et vous ne le savez pas lorsque vous compilez le projet. –

+0

Même si c'est un cours interne? "Les types ou membres internes sont accessibles uniquement dans les fichiers d'un même assembly"? – AnAurelian

1

Si je vais seulement utiliser quelques-unes d'entre elles dans un projet (même un ou deux), si je inclure le fichier WinAPI.cs dans mon projet , sera le .exe final être rempli avec la méthode inutile déclarations Je ne suis pas t en utilisant (l'autre 99 ou plus)?

Oui, tout le code de votre projet sera compilé dans votre assembly;

Qu'en est-structure native déclarations, si je ne suis pas les utiliser dans le projet en cours, seront-ils encore être inclus dans le fichier .exe final?

Oui. Ils seront inclus aussi.

What about constants declarations or readonly members like: 

Oui. Ils seront inclus aussi.

+0

Le compilateur C# ne sait-il pas comment optimiser cela? Pourquoi les inclure s'ils ne sont pas utilisés? – AnAurelian

+0

David - et si vous alliez référencer votre assembly pour l'utiliser comme bibliothèque et que la constante n'était pas là? – Krisc

+0

C'est une classe interne, n'est-ce pas censé être accessible uniquement dans les fichiers du même assemblage? – AnAurelian

2

Tous les éléments que vous avez indiqués seront inclus dans l'assemblage final. La seule façon de se débarrasser d'eux du fichier exe final est l'utilisation des directives précompilation. Par exemple:

#if EXCLUDE_METHODS 

// méthodes non utilisées ici

#endif 
+0

"La portée d'un symbole créé aveC#define est le fichier dans lequel il a été défini." Cela signifie que je ne peux pas définir EXCLUDE_METHODS dans les fichiers source de mon projet C#, je dois le faire dans le fichier WinAPI.cs, ce qui rend impossible la réutilisation de ce fichier. – AnAurelian

+2

Vous pouvez le faire en éditant les propriétés de votre fichier * .csproj. Propriétés-> Construire-> Symboles de compilation conditionnels. Définissez EXCLUDE_METHODS et ce symbole aura une portée d'assemblage. – MichaelMocko

4

Ne transpirez pas des petites choses ici. Ce ne sont que des déclarations, il n'y a pas d'IL pour eux dans l'assemblage final. Ils prennent juste un peu d'espace dans les métadonnées. Les chances sont très élevées qu'elles ne soient même pas chargées à partir de l'assemblage, surtout lorsque vous gardez les déclarations ensemble. Les métadonnées ne sont chargées dans la mémoire RAM que 4096 octets à la fois. Btw, vous ne voulez explicitement pas utiliser readonly pour ces déclarations de constante. Maintenant vous les amener à prendre de l'espace, même quand ils ne sont pas utilisés. Un des rares cas où un const public est une bonne idée. Ce sont des constantes manifestes, leur valeur ne change jamais. Comme Math.PI.