2013-07-10 92 views
1

鑑於接口和下面的類型,我會喜歡有一個PartyDao接口:通用打字混亂

public interface IPartyDao<IdT> : IDao<Party<IdT>> where IdT : struct{} 

因爲編譯器認爲一個締約方未兌換成EntityWithTypedId我不能這樣做。看一個黨的簽名,它似乎黨是一個EntityWithTypedId,因此s/b可轉換成一個。

除了編譯器總是正確的事實,爲什麼它在這種情況下是正確的?有沒有修復?

大部分的污穢,至少美觀,來自使用IDT,但

// IdT is just the id, usually either an int or Guid 
// 
public interface IEntityWithTypedId<out TId> where TId : struct 
{ 
    TId Id { get; } 
} 

// base impl 
public abstract class EntityWithTypedId<TId> : IEntityWithTypedId<TId> where TId:struct 
{ 
    //.. 
} 

// Party *IS* of the right lineage 
public class Party<IdT> : EntityWithTypedId<IdT> where IdT : struct 
{ 
    //.. 
} 

// 
public interface IDao<T, in IdT> 
    where T : EntityWithTypedId<IdT> 
    where IdT : struct 
{ 
    //.. 
} 
+5

當編譯你的代碼時,我得到一個錯誤,指出'IDao'需要兩個泛型參數,而不是你描述的錯誤。 – Servy

+2

另請注意,您在註釋中聲明'TId'可能是'string' - 'string'不是一個結構體,所以限制不會允許您爲'TId'使用'string'。 – Gjeltema

+0

@Gjeltema。過時的文檔好地方! – Berryl

回答

5

你的界面更改爲:

public interface IPartyDao<IdT> : IDao<Party<IdT>, IdT> 
    where IdT : struct { } 

它將編譯。

您在此處發佈的代碼沒有傳遞給IDao的第二個通用參數。

爲了獲得錯誤,您將看到您需要傳遞除IdT以外的類型作爲第二個通用參數。如果你通過一個int(爲了讓第一個編譯器錯誤消失),那麼錯誤就是你不能將Party<IdT>轉換爲EntityWithTypedId<int>。這些類型的泛型參數需要匹配(因爲它們在泛型參數中既不是協變也不是逆變)。

+0

你甚至......你是否只是從錯誤中反向設計正確的問題並回答它呢? –

+0

@Servy。那*令人印象深刻!你有沒有看到有什麼機會在這裏得到共同的或反對的東西?乾杯 – Berryl

+0

@Berryl不,因爲類型不是接口,只有接口可以是co/contra變體。具體類型必須是不變的,它是'EntityWithTypedId',它會在這裏爲你生成錯誤。 – Servy