2010-02-01 6 views
12

Data la classe A, che contiene insiemi di dati grezzi, e la classe B, che contiene una versione riorganizzata (GUI ready) di quei dati, vorrei rendere visibili i dati grezzi in A B.C# Classi di amici e composizione OOP

Chiaramente i dati grezzi in classe A sono contenuti in membri privati. Mi piacerebbe rendere i dati visibili in B attraverso l'uso di qualcosa di simile al metodo delle classi di amici C++.

Come posso avvicinarmi a questo?

Grazie.

risposta

10

In senso stretto, non è possibile definire una classe specifica (o un elenco di classi) a cui è possibile esporre i dati. Tuttavia, è possibile utilizzare il modificatore di accesso internal anziché private, che rende i membri disponibili per qualsiasi classe nello stesso assembly.

Detto questo, si dovrebbe fortemente considera l'esposizione di questi membri attraverso le proprietà piuttosto che i campi (che è quello che sto cercando di indovinare hai intenzione di esporre). Ciò consentirà alla classe di definire esattamente come tali informazioni possono essere esposte ad altre classi e cosa - se mai qualcosa - dovrebbe accadere quando un'altra classe modifica i dati.

+1

'internal' + proprietà = sicura. –

+0

Questo sembra un caso per * proprietà interne * o possibilmente un'interfaccia * * * che la classe di dati sorgente A implementa che consente a B di accedere ad alcuni membri privati ​​senza essere eccessivamente legato a A. – LBushkin

+1

@LBushkin: un'interfaccia interna è certamente una soluzione, ma sembra inutile a meno che non ci sia effettivamente più di una classe che la implementa. –

1

È possibile definire entrambi in un assieme e contrassegnare i campi in A come "interni".

Un altro approccio OO consiste nel fornire un insieme di metodi pubblici in A che consentono l'accesso ai dati (o un sottoinsieme di dati), in genere tramite proprietà semplici.

0

A seconda della struttura, è possibile utilizzare classi parziali. Ciò significherebbe che i dati e l'interfaccia utente sono effettivamente entrambi all'interno della stessa classe, ma li hai all'interno di file diversi.

Se ciò non funziona per te, allora hai variabili interne con scope come alternativa o lavori con Dataset che l'interfaccia utente rappresenta in modo più generico.

0

Il vecchio metodo (gioco di parole) sarebbe definire semplice getvalue() e setvalue() funzioni per restituire quel valore in modo che questi valori potrebbero diventare inaccessibili senza l'uso di queste funzioni, in C# queste funzioni sono membri predefiniti chiamati proprietà.

class TestMethod{ 
private int Secret; 

get { return Secret;} 
set { Secret = value;} 
} 

L'altro metodo è quello di, come altri hanno detto prima di me, basta usare il modificatore internal.

7

Può essere questo potrebbe aiutare ..

public class A 
{ 
    public A() { } 

    public string AccessData(object accessor) 
    { 
     if (accessor is B) 
      return "private_data"; 
     else 
      throw new UnauthorizedAccessException(); 
    } 
} 

public class B 
{ 
    public B() { } 

    private void AccessDataFromA() 
    { 
     Console.WriteLine(new A().AccessData(this)); 
    } 
} 
+2

Questo è un modo intelligente per implementare la semantica di 'friend'.Io non uso sempre 'amico', ma quando lo faccio, uso questo pattern di accesso :-) –

+1

Ma questo rompe solo la sicurezza del tempo di compilazione. Potrei praticamente usare qualsiasi classe su 'AccessData' qui e il compilatore non si lamenterebbe. –