【问题标题】:Strongly typed IDs with generic class具有泛型类的强类型 ID
【发布时间】:2015-07-03 23:42:24
【问题描述】:

我想将我的一些实体 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()) 进行转换时 - 代码编译,但稍后在程序执行中抛出异常:

&lt;System.InvalidCastException&gt; (Unable to cast object of type 'CustomId1[System.Guid]' to type 'FooBarId'.)

我错过了什么?

【问题讨论】:

  • 您使用什么代码来获取使用 FooBarId 的异常
  • @Trisped 我调用了一些命令方法,它接受 FooBarId 作为参数:foo.bar((FooBarId)new Guid())

标签: c# generics strong-typing


【解决方案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&lt;Guid&gt; 不是FooBarId。您需要为从 Guid 转换为该类的每个类定义 am 隐式运算符。

【讨论】:

  • 我想创建该泛型类的原因是通过不在每个 ID 类中定义隐式转换并且仅在泛型类中具有隐式转换来节省一些代码行。但如果那不可能,那么我想我根本不需要那个通用类。谢谢你的帮助。
  • @Andrew 听起来这回答了你的问题。是不是忘记接受了,还是有别的原因?
  • 是的,你回答了我的问题。我忘记接受了。对此感到抱歉。
猜你喜欢
  • 1970-01-01
  • 2020-08-26
  • 1970-01-01
  • 1970-01-01
  • 2015-07-09
  • 2020-03-27
  • 2021-01-25
  • 1970-01-01
相关资源
最近更新 更多