2010-08-25 11 views
8

Sto eseguendo alcune registrazioni diagnostiche con uno dei miei progetti C# .NET e vorrei poter registrare un identificatore che rappresenta un'istanza specifica di una classe. So che potrei farlo con una variabile statica che viene incrementata ogni volta che viene creata un'istanza di classe, ma mi chiedo solo se esiste un modo integrato nel framework .NET per farlo. Forse usando la riflessione o qualcosa del genere.Esiste un modo integrato per identificare le istanze di una classe?

+0

La discussione su questa domanda può essere d'aiuto. http://stackoverflow.com/questions/750947/net-unique-object-identifier –

risposta

5

Giusto per aggiungere a quanto Henk said in his answer su GetHashCode, e per mitigare alcuni dei commenti negativi che ha ricevuto su questo risposta:

C'è un modo per chiamare GetHashCode su qualsiasi oggetto che è indipendente dal valore di tale oggetto , indipendentemente dal fatto che il suo tipo sia stato sostituito o meno da GetHashCode.

Dai uno sguardo allo System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode.

Questo valore non è garantito per essere unico, ovviamente. Né è un Guid (anche se per quel non essere univoco implicherebbe probabilità che sono legittimamente microscopiche).

Direi che il tuo intestino aveva ragione riguardo alla variabile del contatore statico. Devo dire, tuttavia, che semplicemente incrementandolo usando l'operatore ++ nel costruttore di ogni oggetto non è thread-safe. Se è possibile che tu possa istanziare istanze di una classe da più thread, preferiresti usare Interlocked.Increment.

+0

Link interessante. –

3

La cosa più vicina è GetHashCode(), ma non è garantito che sia univoco. Di solito sarebbe sufficiente per la diagnostica.

Ho appena letto le risposte a questo similar question. Secondo JS, l'overhead di allocare un syncblock per la prima chiamata a GethashCode. Questo potrebbe essere un problema.

+0

Il codice GetHash cambia da istanza a istanza? Non dovrebbe cambiare se gli oggetti sono uguali tra loro. – Zebi

+2

Due istanze della stessa classe inizializzate con gli stessi valori dovrebbero restituire lo stesso codice hash, quindi questo non funzionerebbe affatto. –

+1

@Jon B: Questo è vero solo per alcune classi (come la stringa) che sovrascrivono GethashCode(). La versione di default è parte di System.Object e non può vedere i tuoi membri. Provalo. –

0

Forse Object.ReferenceEquals risolve il problema. Almeno ti può dire se un oggetto è uguale a un altro.

Non è possibile utilizzare una variabile statica perché sarà la stessa in ogni istanza. Avrà solo il conteggio degli oggetti creati.

Hai la possibilità di utilizzare la soluzione di Jon B o se desideri che gli identificatori numerici utilizzino un contatore statico e assegni un ID a un campo.

public class Foo 
{ 
    static int counter; 
    public int InstanceId; 

    public Foo() 
    { 
     InstanceId = counter++; 
    } 
} 
+0

Sono abbastanza sicuro che ciò che descrivi nella tua ultima parte è esattamente ciò che l'OP intendeva per "variabile statica" (che sarebbe 'counter'). –

7

Si potrebbe aggiungere una proprietà Guid alla classe un inizializzare nel costruttore (garantito univoco per ogni istanza).

+2

Utilizzato questa tecnica alcune volte. Puoi semplicemente inizializzare direttamente un campo 'public Guid InstanceId = Guid.NewGuid();' per mantenere pulito il tuo costruttore di roba di debug. – Zebi

+0

Non è molto più semplice o più conveniente rispetto all'utilizzo di un contatore statico. È molto più difficile per gli occhi. –

+0

Come utilizzeresti un contatore statico? Sarà lo stesso in ogni istanza poiché è statico. Mi sbaglio? – Zebi

Problemi correlati