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。