具有通用 class 的强类型 ID

Strongly typed IDs with generic class

我想将我的一些实体 ID 更改为强类型。为了避免过多的代码重构,我使用了隐式转换。

这是我目前的情况:

public class FooBarId
{
    private readonly Guid _id;

    public FooBarId(Guid id)
    {
        _id = id;
    }

    public Guid Id
    {
        get { return _id; }
    }

    public static implicit operator Guid(FooBarId id)
    {
        return id.Id;
    }

    public static implicit operator FooBarId(Guid id)
    {
        return new FooBarId(id);
    }
}

此代码运行良好,我无需更改代码中的任何其他内容。

但我想创建更多这样的 classes 并且为了避免重复自己,我创建了一个通用的 class:

public class CustomId<T>
{
    private readonly T _id;

    public CustomId(T id)
    {
        _id = id;
    }

    public T Id
    {
        get { return _id; }
    }

    public static implicit operator T(CustomId<T> id)
    {
        return id.Id;
    }

    public static implicit operator CustomId<T>(T id)
    {
        return new CustomId<T>(id);
    }
}

并试图在我的 FooBarId class 中继承它:

public class FooBarId : CustomId<Guid>
{
}

然后我的代码因使用 FooBarId 的异常而中断:

Argument type 'System.Guid' is not assignable to parameter type 'FooBarId'.

当我尝试像这样转换它时 foo.bar((FooBarId)new Guid()) - 代码编译,但稍后在程序执行中抛出异常:

<System.InvalidCastException> (Unable to cast object of type 'CustomId1[System.Guid]' to type 'FooBarId'.)

我在这里错过了什么?

这对我有用:

class Program
{
    static void Main(string[] args)
    {
        Guid result1 = (CustomId<Guid>)new CustomId<Guid>(Guid.NewGuid());
        Guid result2 = (CustomId<Guid>)new FooBarId();
        Guid result3 = (FooBarId)new FooBarId();
        Guid result4 = new FooBarId();

        CustomId<Guid> cIResult = Guid.NewGuid();
    }
}

public class CustomId<T>
{
    private readonly T _id;

    public CustomId(T id)
    {
        _id = id;
    }

    public T Id
    {
        get { return _id; }
    }

    public static implicit operator T(CustomId<T> id)
    {
        return id.Id;
    }

    public static implicit operator CustomId<T>(T id)
    {
        return new CustomId<T>(id);
    }
}

public class FooBarId : CustomId<Guid>
{
    public FooBarId()
        : base(Guid.NewGuid())
    {
    }
}

您不能执行 (FooBarId)new Guid(),因为 CustomId<Guid> 不是 FooBarId。您需要为每个从 Guid 转换为 class.

的 class 定义隐式运算符