让 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>();

    //...
}