让 class 拥有唯一的 id,无论如何都不会改变
Let class have unique id which doesn't ever change, no matter what
我有 classes 在开发过程中可能会或可能不会更改其名称(和成员)。我的 classes 像枚举一样使用(在大多数情况下),但我不能使用枚举,因为我需要更多的功能。由于 classes(显然)在表面下没有表示它们的整数,所以我需要创建一些具有类似功能的解决方案。换句话说,我希望每个 class 都由一个整数(或其他一些唯一标识符)表示。
我创建了这个属性:
public class IdAttribute : Attribute
{
private int id = -1;
public IdAttribute(int index)
{
this.id = index;
}
public int Id
{
get
{
return id;
}
}
}
我正在使用它如下:
[Id(0)]
public class Hello: Core { }
[Id(1)]
public class Bye: Core { }
如您所见,它很容易出错,因为我不希望任何 class 具有相同的 ID。因此,最理想的情况是我想要一个自动生成的 ID,但如果我更改了有关 class 的任何内容,例如 class 名称或其成员,我不希望它发生变化。
实现此目标的最佳方法是什么?
(我知道在 Java 中,一旦你使 class 可序列化,你将获得一个自动生成的 id(C# 中有类似的东西吗?)
编辑:
我 "couldn't" 只使用枚举的原因是(主要)方便。我有 classes,它在编辑器中公开字段。在这个编辑器中,我只能 select 适当的 "enums",在某些情况下,只会显示继承自 "Core" 的枚举,而在其他情况下,它们可能继承自 "Tools" 或其他一些 class。我希望一切都清楚了。
不确定为什么需要这样做,但您可以执行以下操作:
[AttributeUsage(AttributeTargets.Class)]
public class IdAttribute:Attribute
{
public Guid Id { get; }
public IdAttribute(string id)
{
Id = new Guid(id);
}
}
你会像这样使用它:
[IdAttribute("7d7952d1-86df-4e2e-b040-fed335aad775")]
public class SomeClass
{
//example, you'd obviously cache this
public Guid Id => GetType().GetCustomAttribute<IdAttribute>().Id;
//...
}
请注意,Guid
不是随机的。如果您需要一个随机 ID,那么这不是解决方案。要生成 Guid
阅读对您的问题的评论。
你可以通过你的基地来处理 class Core
:
public abstract class Core
{
public Core()
{
Type myType = this.GetType();
object[] attrs = myType.GetCustomAttributes(typeof(IdAttribute), false);
IdAttribute attr = attrs?.OfType<IdAttribute>().FirstOrDefault();
int id = -1;
if (attr != null) id = attr.Id;
if (!reservedIdentities.ContainsKey(id))
{
reservedIdentities.Add(id, myType);
}
else
{
if (!reservedIdentities[id].Equals(myType))
throw new ArgumentException("Duplicate identities discovered.", nameof(id));
}
}
static Dictionary<int, Type> reservedIdentities = new Dictionary<int, Type>();
//...
}
我有 classes 在开发过程中可能会或可能不会更改其名称(和成员)。我的 classes 像枚举一样使用(在大多数情况下),但我不能使用枚举,因为我需要更多的功能。由于 classes(显然)在表面下没有表示它们的整数,所以我需要创建一些具有类似功能的解决方案。换句话说,我希望每个 class 都由一个整数(或其他一些唯一标识符)表示。
我创建了这个属性:
public class IdAttribute : Attribute
{
private int id = -1;
public IdAttribute(int index)
{
this.id = index;
}
public int Id
{
get
{
return id;
}
}
}
我正在使用它如下:
[Id(0)]
public class Hello: Core { }
[Id(1)]
public class Bye: Core { }
如您所见,它很容易出错,因为我不希望任何 class 具有相同的 ID。因此,最理想的情况是我想要一个自动生成的 ID,但如果我更改了有关 class 的任何内容,例如 class 名称或其成员,我不希望它发生变化。
实现此目标的最佳方法是什么?
(我知道在 Java 中,一旦你使 class 可序列化,你将获得一个自动生成的 id(C# 中有类似的东西吗?)
编辑: 我 "couldn't" 只使用枚举的原因是(主要)方便。我有 classes,它在编辑器中公开字段。在这个编辑器中,我只能 select 适当的 "enums",在某些情况下,只会显示继承自 "Core" 的枚举,而在其他情况下,它们可能继承自 "Tools" 或其他一些 class。我希望一切都清楚了。
不确定为什么需要这样做,但您可以执行以下操作:
[AttributeUsage(AttributeTargets.Class)]
public class IdAttribute:Attribute
{
public Guid Id { get; }
public IdAttribute(string id)
{
Id = new Guid(id);
}
}
你会像这样使用它:
[IdAttribute("7d7952d1-86df-4e2e-b040-fed335aad775")]
public class SomeClass
{
//example, you'd obviously cache this
public Guid Id => GetType().GetCustomAttribute<IdAttribute>().Id;
//...
}
请注意,Guid
不是随机的。如果您需要一个随机 ID,那么这不是解决方案。要生成 Guid
阅读对您的问题的评论。
你可以通过你的基地来处理 class Core
:
public abstract class Core
{
public Core()
{
Type myType = this.GetType();
object[] attrs = myType.GetCustomAttributes(typeof(IdAttribute), false);
IdAttribute attr = attrs?.OfType<IdAttribute>().FirstOrDefault();
int id = -1;
if (attr != null) id = attr.Id;
if (!reservedIdentities.ContainsKey(id))
{
reservedIdentities.Add(id, myType);
}
else
{
if (!reservedIdentities[id].Equals(myType))
throw new ArgumentException("Duplicate identities discovered.", nameof(id));
}
}
static Dictionary<int, Type> reservedIdentities = new Dictionary<int, Type>();
//...
}