如何获取List <t>的唯一ID

时间:2015-07-15 09:12:45

标签: c# uniqueidentifier generic-list

我有一个module MyEngine class MyEngine < Rails::Engine config.before_initialize do config.i18n.load_path += Dir["#{config.root}/config/locales/**/*.yml"] end end end ,其中module MyEngine class MyEngine < Rails::Engine initializer 'MyEngine', before: :load_config_initializers do Rails.application.config.i18n.load_path += Dir["#{config.root}/config/locales/**/*.yml"] end end end 是一个$(function () { var chart = new Highcharts.Chart({ chart: { renderTo: 'container' }, title: { text: 'Step line ends prematurely' }, series: [{ data: [[0, 1], [1, 2], [3, 4]], name: 'Longer' }, { data: [[0, 2], [1, 3]], name: 'Shorter' }] }); }); 字段List<T>。获取T中任何对象中尚未使用的唯一int值的最佳方法是什么?

此程序通常如何编码?是否有数据类型可以帮助解决这个问题,还是需要存储最大的id值?

修改

当我获得1的对象的id时,我将如何从List中删除该对象。当我创建一个新对象时,我希望唯一的id为2.在这种情况下,有没有比存储最后一个唯一ID更好的方法?

感谢。

2 个答案:

答案 0 :(得分:1)

对于这种方法,我写了一个继承的List&lt; T&gt;它保存逻辑,因此您无需在访问列表的任何位置实现它。 如果你有一个具有Id值的最小接口,你甚至可以保持通用。

interface IWithId {
    int Id { get; set; }
}

class CustomList<T> : List<T> where T : class, IWithId {
    private lastUsedId = 1;

    public void AddObjectWithAutomaticId(T newObject) {
        newObject.Id = lastUsedId++;
        base.Add(newObject);
    }

    public T GetElementById(int id) {
         return base.SingleOrDefault(p => p.Id == id);
    }
}

Remove方法仍然可以像以前一样工作。该类存储上次使用的Id,独立于您删除的内容。当您想要添加具有给定ID的对象而不是自动填充它时,Add方法仍然可用。

答案 1 :(得分:0)

我同意GUID适合您作为id属性的评论。但是,如果您需要使用int,那么我建议使用一个新类。

继承List<T>的问题是您必须覆盖多个方法,以确保Add()AddRange()Insert()之类的内容无法添加重复的ID并更新存储的最大ID。很容易错过一个。

我会使用一个不继承任何东西但在内部使用字典的类。这将不会与List<T>具有相同的方法,但这不一定是坏事 - 它可以避免出错,并且您可以使用ToList()方法来查询它,就好像这是一个List<T>

使用上一个答案的一部分来确保T具有Id属性:

interface IHasId {
    int Id { get; set; }
}

class AutoIdList<T> where T : class, IHasId {
    private readonly IDictionary<int, T> _dictionary = new Dictionary<int, T>();
    //Using this list ensures you don't duplicate ids even
    //for an item added with an explicit id then removed
    private IList<int> _historicalIds = new List<int>();
    private int highestAutoGeneratedId = 0;

    public List<T> ToList() {
        return _dictionary.Values.ToList();
    }

    public void Add(T item, bool generateId) {
        if (generateId) {
            highestAutoGeneratedId = NextId();
            T.Id = highestAutoGeneratedId;
        }
        Add(T);
    }

    public void Replace(T item) {
        _dictionary[item.Id] = item;
    }

    public void Remove(T item) {
        _dictionary.Remove(item.Id);
    }

    private void Add(T item) {
        if (_historicalIds.Contains(T.Id)) {
            //throw an appropriate exception
        } else {
            _historicalIds.Add(T.Id);
            _dictionary.Add(T.Id, T);
        }
    }

    private int NextId() {
        var id = highestAutoGeneratedId + 1;
        while (_historicalIds.Contains(id)) {
            id++;
        }
        return id;
    }

    //More methods to simulate AddRange, Insert, etc if required. Leave if not.
    //Should all have simple logic but require checking of Id if adding anything
    //Also need logic to maintain the list of used ids
}