具有泛型类的强类型ID

时间:2015-07-03 23:42:24

标签: c# generics strong-typing

我想将部分实体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);
    }
}

此代码工作正常,我无需更改代码中的任何其他内容。

但是我想创建更多这样的类,为了避免重复自己,我创建了一个泛型类:

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课程中继承它:

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'.)

我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

这对我有用:

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转换为该类的每个类定义隐式运算符。