Идентификатор уникального объекта.NET

Но что-то говорит мне, что это уродливо и есть лучший способ.

blockquote>

Я полностью согласен с твоим предположением.

Кажется, что вы на самом деле имеете некоторые знания о реальных типах, но просто хотите, чтобы единственное место десериализовало эту информацию. Предполагать, что иметь единственную структуру данных, которая представляет полностью несвязанные вещи, является плохой идеей, так как вы в конечном итоге сталкиваетесь с каким-то странным кошмаром для решения проблемы приведения типов и проверки типов. В частности, вы можете легко написать код, который не будет работать во время выполнения:

var a = (int)dict["Connection"];

Вместо этого у вас должен быть статически типизированный тип данных, который представляет эту информацию. Создайте класс, который имеет все эти атрибуты, и используйте некоторую сериализаторную библиотеку, такую ​​как Newtonsofts JSON.Net , чтобы десериализовать атрибуты в эту структуру данных.

class Settings
{
    public int Brightness { get; set; }
    public string Connection { get; set; }
}

Теперь вы можете легко десериализовать ваши настройки:

var setting = JsonConvert.DeserializeObject(myJson)

и иметь полностью детерминированное поведение:

var b = setting.Brightness; // no casting to int neccessary
112
задан Community 23 May 2017 в 12:02
поделиться

5 ответов

Ссылка является уникальным идентификатором объекта. Я не знаю ни одного способа преобразования этого во что-то вроде строки и т. Д. Значение ссылки изменится во время сжатия (как вы видели), но каждое предыдущее значение A будет изменено на значение B, насколько это возможно. что касается безопасного кода, то он по-прежнему является уникальным идентификатором.

Если задействованные объекты находятся под вашим контролем, вы можете создать отображение, используя слабые ссылки (чтобы избежать предотвращения сбора мусора) из ссылки на идентификатор по вашему выбору (GUID, целое число, что угодно). Это, однако, добавило бы определенное количество накладных расходов и сложности.

40
ответ дан Jon Skeet 24 November 2019 в 02:51
поделиться

Может помочь RuntimeHelpers.GetHashCode () ( MSDN ).

35
ответ дан larsmoa 24 November 2019 в 02:51
поделиться

Вы можете развить свою собственную вещь за секунду. Например:

   class Program
    {
        static void Main(string[] args)
        {
            var a = new object();
            var b = new object();
            Console.WriteLine("", a.GetId(), b.GetId());
        }
    }

    public static class MyExtensions
    {
        //this dictionary should use weak key references
        static Dictionary<object, int> d = new Dictionary<object,int>();
        static int gid = 0;

        public static int GetId(this object o)
        {
            if (d.ContainsKey(o)) return d[o];
            return d[o] = gid++;
        }
    }   

Вы можете самостоятельно выбрать, что вы хотите иметь в качестве уникального идентификатора, например, System.Guid.NewGuid () или просто целое число для быстрого доступа.

7
ответ дан majkinetor 24 November 2019 в 02:51
поделиться

Вы должны будете назначить такой идентификатор самостоятельно, вручную - либо внутри экземпляра, либо снаружи.

Для В записях, связанных с базой данных, первичный ключ может быть полезен (но вы все равно можете получить дубликаты). В качестве альтернативы, либо используйте Guid , либо оставьте свой собственный счетчик, выделяя его с помощью Interlocked.Increment (и сделайте его достаточно большим, чтобы он не переполнился).

3
ответ дан Marc Gravell 24 November 2019 в 02:51
поделиться

Checked out the ObjectIDGenerator class? This does what you're attempting to do, and what Marc Gravell describes.

The ObjectIDGenerator keeps track of previously identified objects. When you ask for the ID of an object, the ObjectIDGenerator knows whether to return the existing ID, or generate and remember a new ID.

The IDs are unique for the life of the ObjectIDGenerator instance. Generally, a ObjectIDGenerator life lasts as long as the Formatter that created it. Object IDs have meaning only within a given serialized stream, and are used for tracking which objects have references to others within the serialized object graph.

Using a hash table, the ObjectIDGenerator retains which ID is assigned to which object. The object references, which uniquely identify each object, are addresses in the runtime garbage-collected heap. Object reference values can change during serialization, but the table is updated automatically so the information is correct.

Object IDs are 64-bit numbers. Allocation starts from one, so zero is never a valid object ID. A formatter can choose a zero value to represent an object reference whose value is a null reference (Nothing in Visual Basic).

39
ответ дан 24 November 2019 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: