2016-06-30 5 views
0

Le sujet dans lequel je suis actuellement est le partage de code. Il est suggéré d'utiliser le modificateur d'accès internal pour partager le code entre plusieurs fichiers. Mais est-ce? Ou est-ce que je me trompe? Je ne peux pas poster le lien, car la source n'est pas accessible à tout le monde.Est-ce que le modificateur d'accès `internal` peut être utilisé pour diviser une classe sur plusieurs fichiers?

Est-il possible d'avoir la définition d'une classe dans un fichier (comme une interface, ou une classe abstraite) et de l'implémenter dans un autre fichier (et d'utiliser ici internal)?

Voici un pseudo code (qui ne fonctionne évidemment pas). Définition dans un seul fichier:

internal static class SongLoader 
{ 
    internal async static Task<IEnumerable<Song>> Load(); 
    internal async static Task<Stream> OpenData(); 
} 

mise en œuvre dans un autre fichier:

internal static class SongLoader 
{ 
    internal const string Filename = "songs.json"; 

    internal static async Task<IEnumerable<Song>> Load() 
    { 
     // implementation 
    } 

    internal static Stream OpenData() 
    { 
     // implemenation 
    } 
} 

Ou est-il possible d'avoir Load() définis dans un fichier et OpenData() dans un autre, tout en utilisant internal modificateur d'accès? Est-ce possible? Comment?

+0

dans les fichiers dans le même assembly: https://msdn.microsoft.com/fr-fr/library/7c5ka91b.aspx –

+0

@Stanley: Oui, il doit être dans le même assembly car il est compilé dans le même projet (Voir [Projets partagés] (https://developer.xamarin.com/guides/cross-platform/application_fundamentals/shared_projects/)). – grabner

+1

'internal' est juste un modificateur de visibilité. Cela n'a rien à voir avec la division d'une classe en plusieurs fichiers. Le mot-clé pour cela est «partial». Mais il n'y a pas de «définition d'une classe» que vous décrivez. Les choses les plus proches sont les "méthodes partielles", mais elles doivent renvoyer "void" et ce sont toujours des méthodes privées. –

Répondre

2

internal spécificateur est utilisé pour limiter les classes/membres étant utilisé autrement que dans l'ensemble contenant.

Le partage de code est réalisé via les classes partial. Vous pouvez avoir une partie d'une classe dans un fichier et l'autre partie dans un autre fichier.

Dans un fichier

public partial class MyClass 
{ 
    public void Foo() 
    { 
    } 
} 

Dans le fichier B

public partial class MyClass 
{ 
    public void Bar() 
    { 
    } 
} 

Vous ne pouvez pas avoir la déclaration dans un seul fichier et la définition dans un fichier comme dans C++. Si vous avez de telles exigences, vous devriez penser aux classes interface ou abstract.

+0

Dans mon cas, il serait utile de cacher un membre entre différentes assemblées. Je pourrais donc avoir différentes implémentations, mais aussi utiliser le même "contrat". A propos de la scission de la déclaration et de la définition: Ce n'était qu'un exemple pour atteindre le partage de code. Dans mon exemple concret, 'Foo()' appelle 'Bar()', mais il existe différentes variantes de 'Bar()' en fonction de l'assemblage. – grabner

+0

Vous ne pouvez pas avoir la même fonction implémentée spécifiquement pour différents assemblages. Si vous en dites plus sur le problème que vous avez, alors nous pouvons discuter de solutions alternatives. –

+0

Je veux acquérir quelques connaissances dans les options de partage de code. 'internal' a été mentionné comme l'une des options (en plus de' partial'). Donc 'internal' ne semble pas aider avec le partage de code. Maintenant, j'ai essayé d'utiliser 'partial' comme vous l'avez suggéré, mais je ne vois pas tous les avantages ici. Si vous êtes intéressé, vous pouvez regarder dans mes essais [ici] (https://codeshare.io/dDOXz). – grabner

4

internal est un modificateur d'accès qui traite du code pouvant accéder à vos fonctions. Ce que vous cherchez est le mot-clé partial si vous voulez diviser une classe en plusieurs fichiers dans le même espace de noms.

https://msdn.microsoft.com/en-us/library/wa80x488.aspx

partial vous ne laissera pas définir la même définition de fonction deux fois; vous devrez remplacer ou virtualiser, ou travailler avec une classe de base si c'est ce que vous visez. Partiel est pratique à certains moments, mais il peut conduire à une solution quelque peu encombrée si vous n'êtes pas sûr de quelle classe peut être trouvé où.

+1

Vous ne pouvez pas non plus définir la même fonction deux fois avec des classes partielles, ce que je pense est ce que l'OP veut –

+0

Vous avez raison, s'il cherche deux fois la même définition de fonction, cela ne fonctionnera pas. Vous devez remplacer une fonction de base si c'est l'itinéraire que vous recherchez. J'ai ajouté ce commentaire à ma réponse, juste pour être sûr. – MartijnK

1

Les modificateurs d'accès ne traitent que de qui peut voir le code, pas comment il est implémenté.
Le moyen le plus proche de faire ce que vous voulez est d'utiliser abstract classes.

A titre d'exemple:

internal abstract class SongLoader //under SongLoader.cs 
{ 
    internal async virtual Task<IEnumerable<Song>> Load(); 
    internal async virtual Task<Stream> OpenData(); 
} 

internal sealed class SongLoaderImplementer : SongLoader //under SongLoaderImplementer.cs 
{ 
    internal override async Task<IEnumerable<Song> Load() {} 
    internal override async Task<Stream> OpenData() {} 
}