2015-07-03 290 views
1

我想将一些实体ID更改为强类型。为了避免过多的代码重构,我使用了隐式转换。使用泛型类的强类型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'.)

缺少什么我在这里?

+0

你使用什么代码来获得使用FooBarId的异常_? – Trisped

+0

@Trisped我调用了一些命令方法,它接受FooBarId作为参数:'foo.bar((FooBarId)new Guid())' – Andrew

回答

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

+0

我想创建泛型类的原因是通过不保存一些代码行在每个ID类中定义隐式转换并仅在泛型类中进行。但如果这是不可能的,那么我想我根本不需要那个泛型类。谢谢你的帮助。 – Andrew

+0

@Andrew听起来像这回答你的问题。你忘了接受,还是有别的? – Trisped

+0

是的,你回答了我的问题。我忘了接受它。对于那个很抱歉。 – Andrew