首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >System.Runtime.Serialization::ObjectIDGenerator

System.Runtime.Serialization::ObjectIDGenerator
EN

Stack Overflow用户
提问于 2012-11-18 20:28:47
回答 1查看 681关注 0票数 0

我只是尝试在我的应用程序中使用System.Runtime.Serialization::ObjectIDGenerator。我的应用程序需要与另一个进程通信。为此,我需要在进程之间交换对象I。ObjectIDGenerator类似乎是解决方案..。直到我发现有一个查找对象-> ID,但没有查找ID ->对象。

有没有一个更好的现成的解决方案,允许可靠和快速的查找两个方向?

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2012-11-20 06:50:01

ObjectIDGenerator只是在它看到的对象上保留了一个哈希表,以及一个指定的对象id。

以下是C#中的简化版本:

代码语言:javascript
复制
public class MyObjectIdGenerator
{
    private Dictionary<int,List<int>> _hashToID = new Dictionary<int,List<int>>();
    private List<object> _objects = new List<object> { null, };
    private int _idCounter = 1;
    private int _numRemoved = 0;

    public int GetId(object obj)
    {
        if (obj == null)
        {
            return 0;
        }

        int hash = RuntimeHelpers.GetHashCode(obj);

        List<int> ids;
        if (!_hashToID.TryGetValue(hash, out ids))
        {
            ids = new List<int>();
            _hashToID[hash] = ids;
        }

        foreach (var i in ids)
        {
            if (ReferenceEquals(_objects[i], obj))
            {
                return i;
            }
        }

        // Move the counter to the next free slot.
        while (_idCounter < _objects.Count && _objects[_idCounter] != null)
        {
            _idCounter++;
        }

        int id = _idCounter++;
        ids.Add(id);

        // Extend the pool to enough slots.
        while (_objects.Count <= id) {
            _objects.Add(null);
        }
        _objects[id] = obj;

        return id;
    }

    public bool Remove(object obj)
    {
        if (obj == null) return false;

        // Locate the object
        int hash = RuntimeHelpers.GetHashCode(obj);
        List<int> ids;
        if (!_hashToID.TryGetValue(hash, out ids)) return false;

        foreach (var i in ids)
        {
            if (ReferenceEquals(_objects[i], obj))
            {
                // Remove the object, and clean up.
                _objects[i] = null;
                ids.Remove(i);
                if (ids.Count == 0)
                {
                    _hashToID.Remove(hash);
                }
                _numRemoved++;
                if (_numRemoved >= 10 && _numRemoved >= _objects.Count/2) {
                    // Too many free slots. Reset the counter.
                    _idCounter = 0;
                    _numRemoved = 0;
                }
                return true;
            }
        }
        return false;
    }

    public object GetObject(int id)
    {
        if (id < 0 || id >= _objects.Count) return null;
        // 0 => null
        return _objects[id];
    }
}

下面是ObjectIDGenerator:http://www.fixee.org/paste/30e61ex/的解压缩源

编辑:添加了Remove方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13444249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档