通用打字混乱

时间:2013-07-10 16:38:54

标签: c# .net generics

鉴于下面的接口和类型,我会喜欢为PartyDao提供一个接口:

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

我不能这样做,因为编译器认为Party不能转换为EntityWithTypedId。要查看Party的签名,似乎该Party是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
{
    //..  
}

1 个答案:

答案 0 :(得分:5)

将您的界面更改为:

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

它会编译。

您在此处发布的代码没有传递给IDao的第二个通用参数。

为了得到您所看到的错误,您需要传递除IdT以外的类型作为第二个通用参数。如果你传递int(为了让第一个编译器错误消失),那么错误就是你无法将Party<IdT>转换为EntityWithTypedId<int>。这些类型的泛型参数需要匹配(因为它们在泛型参数中既不是协变的也不是逆变的。)