I have a collection of objects that have a unique key. That key could be numbers or a string, it's generic and most of the class doesn't care because it's stored in a Dictionary<TKey, TItem>
.
Now the class should provide a method to return a new unique key for an item to be added. That's where I can't find a solution. I've tried to read up on the new generic math feature of C# but that doesn't make any sense to me.
I'm looking for something like the GetUniqueKey method below:
// Restrict TKey to numbers or strings: https://stackoverflow.com/a/30660880
class MyCollection<TKey, TObject>
where TObject : class
where TKey : notnull, IComparable, IConvertible, IEquatable<TKey>
{
private Dictionary<TKey, TObject> items;
public TKey GetUniqueKey()
{
if (TKey is INumber)
return items.Keys.Max() + 1;
if (TKey is string)
return Guid.NewGuid().ToString();
throw new NotSupportedException("Key type not supported.");
}
}
Can this be done at all?
This is what I came up with:
// Restrict TKey to numbers or strings: https://stackoverflow.com/a/30660880
public class MyCollection<TObject, TKey>
where TObject : class
where TKey : notnull, IComparable, IConvertible, IEquatable<TKey>
{
private readonly Dictionary<TKey, TObject> objects = [];
public TKey GetUniqueKey()
{
switch (Type.GetTypeCode(typeof(TKey)))
{
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
if (Count == 0)
return (TKey)Convert.ChangeType(1, typeof(TKey));
return (TKey)Convert.ChangeType(Convert.ToInt64(objects.Keys.Max()) + 1, typeof(TKey));
case TypeCode.UInt64:
if (Count == 0)
return (TKey)Convert.ChangeType(1, typeof(TKey));
return (TKey)Convert.ChangeType(Convert.ToUInt64(objects.Keys.Max()) + 1, typeof(TKey));
case TypeCode.String:
return (TKey)(object)Guid.NewGuid().ToString();
default:
throw new NotSupportedException($"Key type {typeof(TKey).Name} not supported.");
}
}
}
I makes use of IConvertible
for all numbers to convert the types, any also IComparable
for Max()
.