Ich habe eine Anwendung, die eine GUID-Variable hat, die (natürlich) eindeutig sein muss. Ich weiß, dass statistisch jede Guid nur als einzigartig angenommen werden sollte, aber aufgrund von Dev/Test-Umgebungsgründen kann der gleiche Wert mehrmals gesehen werden. Wenn das passiert, möchte ich den Wert des GUID "erhöhen", anstatt nur einen ganz neuen zu erstellen. Es scheint keinen einfachen Weg zu geben, dies zu tun. Ich habe einen Hack gefunden, den ich als mögliche Antwort posten werde, möchte aber eine sauberere Lösung.Inkrementieren Guid in C#
Antwort
Sie können die Byte-Komponenten des guid erhalten, also Sie können sich einfach funktionieren:
static class GuidExtensions
{
private static readonly int[] _guidByteOrder =
new[] { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 };
public static Guid Increment(this Guid guid)
{
var bytes = guid.ToByteArray();
bool carry = true;
for (int i = 0; i < _guidByteOrder.Length && carry; i++)
{
int index = _guidByteOrder[i];
byte oldValue = bytes[index]++;
carry = oldValue > bytes[index];
}
return new Guid(bytes);
}
}
EDIT: jetzt mit der richtigen Byte-Reihenfolge
Warum die Downvotes? Möchten Sie erklären, was mit dieser Antwort nicht stimmt? –
Dieser Code löst eine OverflowException mit ++ aus, wenn der Wert des Bytes 255 ist. Daher müsste {} um diese Anweisung herum deaktiviert werden. – Abacus
@Abacus, ist Ihr Projekt mit der Option '/ checked' kompiliert? Ganzzahlarithmetik ist mit den Standardoptionen deaktiviert. –
Mögliche Lösung - ich denke, das (nicht funktioniert wirklich getestet), aber eine bessere Lösung wollen.
public static Guid Increment(this Guid value)
{
var bytes = value.ToByteArray();
// Note that the order of bytes in the returned byte array is different from the string representation of a Guid value.
// Guid: 00112233-4455-6677-8899-aabbccddeeff
// byte array: 33 22 11 00 55 44 77 66 88 99 AA BB CC DD EE FF
// So the byte order of the following indexes indicates the true low-to-high sequence
if (++bytes[15] == 0) if (++bytes[14] == 0) if (++bytes[13] == 0) if (++bytes[12] == 0) if (++bytes[11] == 0) if (++bytes[10] == 0) // normal order
if (++bytes[9] == 0) if (++bytes[8] == 0) // normal order
if (++bytes[6] == 0) if (++bytes[7] == 0) // reverse order
if (++bytes[5] == 0) if (++bytes[4] == 0) // reverse order
if (++bytes[3] == 0) if (++bytes[2] == 0) if (++bytes[1] == 0) { ++bytes[0]; } // reverse order
return new Guid(bytes);
}
Edit: hier ist der Code, ich endete mit; lehnt sich an die obigen Antworten für die allgemeine Technik an, obwohl sie ohne die "unchecked" -Klausel in einigen Fällen Ausnahmen auslösen würden. Aber ich habe auch versucht, das Folgende so leserlich wie möglich zu machen.
private static int[] _guidByteOrder = { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 };
public static Guid NextGuid(this Guid guid)
{
var bytes = guid.ToByteArray();
for (int i = 0; i < 16; i++)
{
var iByte = _guidByteOrder[i];
unchecked { bytes[iByte] += 1; }
if (bytes[iByte] != 0)
return new Guid(bytes);
}
return Guid.Empty;
}
Diese 'if' Kette ist großartig. – Rawling
Die Verwendung von 'BigInteger' zum Inkrementieren führt zu offensichtlich korrektem und wahrscheinlich gut aussehendem Code. –
Dank Thomas Levesque ‚s-Byte-Reihenfolge, hier ist eine nette LINQ Implementierung:
static int[] byteOrder = { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 };
static Guid NextGuid(Guid guid)
{
var bytes = guid.ToByteArray();
var canIncrement = byteOrder.Any(i => ++bytes[i] != 0);
return new Guid(canIncrement ? bytes : new byte[16]);
}
Hinweis es um zu Guid.Empty
hüllt, wenn Sie sich zu erhöhen, so weit zu verwalten.
Es wäre effizienter, wenn Sie eine einzelne Kopie von bytes
weiter inkrementieren anstatt ToByteArray
nacheinander auf jeder GUID aufzurufen.
Sehr elegant. Sind Sie sich über die Byte-Reihenfolge sicher? –
@ThomasLevesque Es passt zu einigen anderen Orten, die ich gesehen habe. – Rawling
Ich beobachtete diese Reihenfolge: 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 –
Verifiziert Lösung für Bestellte Saiten:
private static Guid Increment(Guid guid)
{
byte[] bytes = guid.ToByteArray();
byte[] order = { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 };
for (int i = 0; i < 16; i++)
{
if (bytes[order[i]] == byte.MaxValue)
{
bytes[order[i]] = 0;
}
else
{
bytes[order[i]]++;
return new Guid(bytes);
}
}
throw new OverflowException("Congratulations you are one in a billion billion billion billion etc...");
}
Überprüfung:
private static Guid IncrementProof(Guid guid, int start, int end)
{
byte[] bytes = guid.ToByteArray();
byte[] order = { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 };
for (int i = start; i < end; i++)
{
if (bytes[order[i]] == byte.MaxValue)
{
bytes[order[i]] = 0;
}
else
{
bytes[order[i]]++;
return new Guid(bytes);
}
}
throw new OverflowException("Congratulations you are one in a billion billion billion billion etc...");
}
static void Main(string[] args)
{
Guid temp = new Guid();
for (int j = 0; j < 16; j++)
{
for (int i = 0; i < 255; i++)
{
Console.WriteLine(temp.ToString());
temp = IncrementProof(temp, j, j + 1);
}
}
}
- 1. Bluetooth GUID in C#
- 2. Inkrementieren einer Konstante in C++
- 3. Roslyn C# Inkrementieren Änderung
- 4. Inkrementieren von C-Zeigern
- 5. va_arg nicht inkrementieren C++
- 6. C# Regex für Guid
- 7. Inkrementieren Immobilien in AWS DynamoDB Objective C
- 8. Inkrementieren von Zeigern in C-Arrays
- 9. Post und pre inkrementieren, dekrementieren in C++
- 10. Zugriff auf Guid Mitglieder in C#
- 11. Einfache Generierung von GUID in C
- 12. Umwandlung einer Guid in Nullable Guid
- 13. C++ inkrementieren std :: atomic_int wenn ungleich Null
- 14. C# Linq Guid Anonymer Typ Problem
- 15. Inkrementieren in MySQL
- 16. Integer in Python inkrementieren
- 17. Inkrementieren Zeichenfolge in Python
- 18. inkrementieren notification.number in android
- 19. GUID in String konvertieren
- 20. Guid Validierung in SQL
- 21. Wie Guid in .net
- 22. Wie Auto Nummer (Auto Inkrement) Guid-Feld in Mysql-Datenbank
- 23. Alphabete inkrementieren
- 24. Inkrementieren Sie den Operator innerhalb des Bedingungsoperators in c
- 25. C# LINQ Inkrementieren Variable in anonymous Wählen Sie
- 26. Inkrementieren eines Zählers in einem Timer (System.Windows.Forms.Timer) C#
- 27. Nullable GUID
- 28. Der effizienteste Weg, um eine Guid in C#
- 29. Warum ist Guid NICHT ein Objekt in C#?
- 30. einen neuen Guid in einem Code-Schnipsel mit C#
Warum kann es nicht eine neue Guid sein? –
Das ist * nicht * wie 'GUID's * behandelt * werden sollen. Was ist falsch daran, 'Guid.NewGuid()' aufzurufen, wenn Sie eine neue benötigen? –
Die Art, wie Sie dies verwenden, möchten Sie vielleicht stattdessen als UUID bezeichnen. – VoidStar