C# 如何获取列表的唯一id<;T>;

C# 如何获取列表的唯一id<;T>;,c#,uniqueidentifier,generic-list,C#,Uniqueidentifier,Generic List,我有一个列表,其中T是一个类,它有一个int字段作为id。如何获得未在列表中的任何对象中使用的唯一id值的最佳方法 这个程序通常是如何编码的?是否有一种数据类型可以帮助实现这一点,或者我是否需要存储最大的id值 编辑 当我得到一个id为1的对象时会怎么样。然后从列表中删除该对象。创建新对象时,我希望唯一id为2。在这种情况下,有没有比存储最后一个唯一id更好的方法 谢谢。对于这种方法,我将编写一个包含逻辑的继承列表类,这样您就不必在访问列表的任何地方都实现它。 如果有一个具有Id值的最小接口,甚

我有一个
列表
,其中
T
是一个类,它有一个
int
字段作为
id
。如何获得未在
列表中的任何对象中使用的唯一
id
值的最佳方法

这个程序通常是如何编码的?是否有一种数据类型可以帮助实现这一点,或者我是否需要存储最大的id值

编辑

当我得到一个id为1的对象时会怎么样。然后从列表中删除该对象。创建新对象时,我希望唯一id为2。在这种情况下,有没有比存储最后一个唯一id更好的方法


谢谢。

对于这种方法,我将编写一个包含逻辑的继承列表类,这样您就不必在访问列表的任何地方都实现它。 如果有一个具有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);
    }
}
接口IWithId{
int Id{get;set;}
}
类CustomList:列表,其中T:class,IWithId{
私人lastUsedId=1;
public void addobjectwithautomatic(T newObject){
newObject.Id=lastUsedId++;
base.Add(newObject);
}
公共T GetElementById(内部id){
返回base.SingleOrDefault(p=>p.Id==Id);
}
}

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

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

继承
列表
的问题是,您必须重写多个方法,以确保诸如
Add()
AddRange()
Insert()
等内容无法添加重复的id并更新存储的最大id。很容易错过一个

我将使用一个不继承任何内容,但在内部使用字典的类。这与
列表
的方法不尽相同,但这并不一定是件坏事-它可以避免出错,并且当他们想像查询
列表一样查询它时,您可以使用
ToList()
方法

使用前面答案的一部分来确保
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
}
接口IHasId{
int Id{get;set;}
}
class AutoIdList,其中T:class,IHasId{
专用只读IDictionary _dictionary=new dictionary();
//使用此列表可确保您甚至不会复制ID
//对于添加了显式id然后删除的项目
私有IList_historicalIds=新列表();
private int highestAutoGeneratedId=0;
公众名单收费表(){
返回_dictionary.Values.ToList();
}
公共无效添加(T项,布尔生成ID){
如果(生成ID){
highestAutoGeneratedId=NextId();
T.Id=最高自动生成Id;
}
加(T);
}
公共无效替换(T项){
_字典[item.Id]=项;
}
公共作废删除(T项){
_dictionary.Remove(item.Id);
}
专用作废添加(T项){
if(_historcalids.Contains(T.Id)){
//抛出适当的异常
}否则{
_添加(T.Id);
_添加(T.Id,T);
}
}
私有int NextId(){
var id=最高自动生成id+1;
while(_historcalids.Contains(id)){
id++;
}
返回id;
}
//如果需要,可以使用更多的方法来模拟AddRange、Insert等。如果不需要,请离开。
//应该都有简单的逻辑,但如果添加任何内容,则需要检查Id
//还需要逻辑来维护已使用ID的列表
}

第一步是说明您使用的语言。使用类
T
的hashcode作为标识,或者您可以为标识创建一个GUID。