Domanda

C'è un C # equivalente di Python id () ? Se no, come posso verificare se un oggetto è cambiato? Ad esempio, in Python, un oggetto immutabile:

>>> s = "abc"
>>> id(s)
11172320
>>> s += "d"
>>> id(s)
18632928

ed uno mutabile:

>>> a = [1, 2, 3]
>>> id(a)
11259656
>>> a += [4]
>>> id(a)
11259656

Modifica - La maggior parte delle risposte finora sono circa funzioni di confronto / operatori , ma io sono più interessato a dei valori che vengono confrontati. Non ero inizialmente chiari su questo, e sto accettando Object.ReferenceEquals come la risposta.

È stato utile?

Soluzione

Bene, è possibile utilizzare la funzione di Object.ReferenceEquals() :

Determina se le istanze di Object specificate rappresentano la stessa istanza.

Per prendere in prestito il tuo esempio di Python un po ':

List<int> listA = new List<int> { 1, 2, 3 };
List<int> listB = listA;
listA.Add(4);

bool equal = object.ReferenceEquals(listA, listB);

equal sarà true.

Altri suggerimenti

È possibile verificare l'identità oggetto con Object.ReferenceEquals .

credo che tu stia facendo la domanda sbagliata. La mia risposta è abbastanza dettagliato, ma ecco un breve riassunto:

  • Non v'è alcun equivalente diretto a id in C #.
  • È possibile ottenere ottenere l'indirizzo di un oggetto in C # utilizzando i puntatori, ma è non dovrebbe usare questo per risolvere il problema.
  • Il metodo object.ReferenceEquals fa qualcosa di simile a ciò che si sta cercando di fare.
  • Il problema che si sta tentando di risolvere non esiste realmente in C # nello stesso modo è lo fa in Python.
  • Il modo in cui si utilizza id non risolve il problema in Python sia.

In primo luogo, vi posterò dal documentazione per id poiché la maggior parte persone non sembrano averlo letto. Si prega di leggere questo perché il resto della mia risposta ha senso solo se si sa cosa id fa (e no, non crea un codice hash):

Ritorna la “identità” di un oggetto. Questo è un numero intero (o intero lungo) che è garantito per essere unico e costante per questo oggetto durante la sua vita. Due oggetti con vite non sovrapposte possono avere lo stesso valore di id ().

CPython dettaglio di implementazione:. Questo è l'indirizzo dell'oggetto

C # non ha un equivalente id ma è possibile per ottenere l'indirizzo dell'oggetto da ottenere un puntatore all'oggetto in modalità non sicura.

unsafe
{
     IntPtr x = (IntPtr)(&v);
     Console.WriteLine(x);
}

Tuttavia è non dovrebbe fare questo in C #. È molto raramente necessario utilizzare codice unsafe in C #, e se lo fai può facilmente diffondersi come codice che chiama il codice diventa anche pericoloso. Ci sono altri modi per risolvere il problema che non ha bisogno del codice non sicuro. Inoltre, in .NET (a differenza di Python) gli oggetti possono essere spostati su in memoria dal garbage collector, quindi se volete una singola identità che rimane costante per tutta la durata dell'oggetto, l'indirizzo di memoria è di alcuna utilità per voi. Si dovrebbe invece creare una proprietà di sola lettura, denominata Id per esempio.


Un approccio alternativo che è possibile in C # senza utilizzare codice non sicuro è quello di testare se due variabili hanno lo stesso riferimento utilizzando Object.ReferenceEquals . Tuttavia probabilmente non dovrebbe farlo neanche. C # non ha la stessa ambiguità come in Python. Per impostare una variabile per puntare a un nuovo oggetto si utilizza l'operatore =. Chiamare un metodo quasi sempre non cambierà il riferimento, quindi non dovreste preoccuparvi di questo. In C # operatore x += y; è (quasi) equivalente a x = x + y e non è possibile cambiare la situazione, come si può in Python.


Inoltre, come accennato nella documentazione, il vostro esempio Python è viziata - id non può essere utilizzato in modo affidabile per verificare se un oggetto è cambiato. Esempio:

>>> s='abc'
>>> id(s)
37822208
>>> s+='d'
>>> id(s)
61711680    # Changes
>>> s+='e'
>>> id(s)
61711680    # Oops... doesn't change even though the value changed.

In Python se si deve confrontare due oggetti per vedere se sono lo stesso oggetto (e probabilmente non dovrebbero fare questo), quindi utilizzare is che è l'equivalente di Python object.ReferenceEquals. id è garantita solo per essere costante per tutta la durata di un oggetto. Come mostrato sopra id è non garantita diverso per oggetti diversi. In particolare, se uno degli oggetti non esiste più è possibile (ed a volte sarà) ottenere la stessa id a causa di riutilizzo della stessa memoria. Come tale l'uso di id è una pessima idea.

Riepilogo

Non farlo.

object.GetHashcode() potrebbe valere la pena un colpo.

wes, la risposta corretta alla tua domanda, vale a dire .. una funzione analoga a id () è

object.GetHashCode ()

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top