2015-07-03 288 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