C# 不能同时指定约束类和';类别';或';结构';约束

C# 不能同时指定约束类和';类别';或';结构';约束,c#,generics,C#,Generics,我试图通过创建IDbSet的自定义模拟来解决问题 自定义模拟: public class DbSetMock : IDbSet<Tenant> { /* hidden all other implemented methods/properties */ public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, Tenant { thr

我试图通过创建IDbSet的自定义模拟来解决问题

自定义模拟:

public class DbSetMock : IDbSet<Tenant>
{
    /* hidden all other implemented methods/properties */

    public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, Tenant
    {
        throw new NotImplementedException();
    }
}
公共类DbSetMock:IDbSet
{
/*隐藏所有其他实现的方法/属性*/
public TDerivedEntity Create(),其中TDerivedEntity:类,租户
{
抛出新的NotImplementedException();
}
}
create方法给出了一个构建错误,我不知道如何解决:

无法同时指定约束类和“类”或“结构”约束

简单地从约束中删除
class
会导致另一个构建错误(我也不理解:())

方法'Test.dal.tAddi蚁.dBestMoCK.Cudie()的类型参数“TestDead实体”的约束必须匹配接口方法'Stase.DATa.实体.IDBSET(CREATE())的类型参数'TrPrimeDebug实体的约束.请考虑使用显式接口实现来代替. < /P>


有人能帮我成功构建这个类吗?

因为
t派生的
type参数被约束为
Tenant
,添加约束
class
struct
是多余的。只需删除
class
约束即可

更新:奇怪的是,这里的编译器错误之间似乎存在冲突。如果你“修复”了其中一个,你就会在绝望中得到另一个。幸运的是,第二个错误也给了我们一条出路:你可以使用显式接口实现:

public class DbSetMock : IDbSet<Tenant>
{

    TDerivedEntity IDbSet<Tenant>.Create<TDerivedEntity>()
    {
        throw new NotImplementedException();
    }

}
公共类DbSetMock:IDbSet
{
TDerivedEntity IDbSet.Create()
{
抛出新的NotImplementedException();
}
}
如果不使用显式接口实现,似乎无法实现该方法。如果需要将其作为类的公共接口的一部分,我建议创建接口实现转发到的另一个方法:

public class DbSetMock : IDbSet<Tenant>
{

    TDerivedEntity IDbSet<Tenant>.Create<TDerivedEntity>()
    {
        return Create<TDerivedEntity>();
    }

    public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : Tenant
    {
        throw new NotImplementedException();
    }

}
公共类DbSetMock:IDbSet
{
TDerivedEntity IDbSet.Create()
{
返回Create();
}
公共TDerivedEntity Create(),其中TDerivedEntity:租户
{
抛出新的NotImplementedException();
}
}

尝试从方法部分删除
,如下所示

public class DbSetMock : IDbSet<Tenant>
    {
        /* hidden all other implemented methods/properties */

        public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : Tenant
        {
            throw new NotImplementedException();
        }
    }
公共类DbSetMock:IDbSet
{
/*隐藏所有其他实现的方法/属性*/
公共TDerivedEntity Create(),其中TDerivedEntity:租户
{
抛出新的NotImplementedException();
}
}

类,租户
是冗余代码。

它告诉您的是约束:

class, Tenant

是多余的。您只需删除
,因为
租户
更受约束,并且包含

目前框架中只有三个可继承的类,它们的后代可能是值类型:
对象
值类型
,以及
枚举
。所有这三个类这些类型中的任何类型都是类类型,但是从
ValueType
Enum
派生的任何类型都将是值类型,而从
Object
派生的任何类型如果不是从
ValueType
派生的,都将是类类型。对于除上述类型之外的任何类型,都将使用
class
struct
约束冗余或矛盾;C#不允许直接为上述类型指定约束,这并非巧合

在某些语言和框架中,一种流行的设计理念是,如果存在一种特定的表达形式,而适用于该一般形式的行为将是无用的,那么语言/框架设计师没有理由特意禁止这种形式。在这种理念下,拥有e受限于密封类型的泛型类型(例如
Fnord)
。如果所讨论的类型是密封的,那么这样的事情将毫无意义,将来的版本也不会是密封的,但是因为对这种情况应用泛型约束的正常解释将产生合理的行为,而且可以想象,在某些情况下,这种约束可能是有用的(例如,编写代码以使用正在开发且目前已密封的类,但在其最终版本中可能会密封,也可能不会密封,或者编写代码以与期望特定泛型形式的基于反射的代码接口),该理念建议将泛型类型限制为密封类应该是合法的

在其他一些语言和框架中,有一种不同的理念:如果程序员可能期望某个特定形式的构造提供超出一般形式的功能,但实际上并非如此,并且如果没有这些功能,该特定形式似乎不太有用,则该语言应该禁止它,即使该构造具有精确的m这是一种定义良好的语言,如果语言的实现者看不到程序员想要表达这种实际意义的理由,就不能通过其他方式来表达

C#和.net都不存在将一个类型参数约束到另一个类型参数的问题,即使另一个参数的类型不会被接受为约束,这一事实表明,由于上述理念,语言人为地施加了限制。不幸的是,IMHO,因为有很多在某些情况下,如果能够说:

bool HasAnyFlags<T>(this T enum1, T enum2) where T:struct,System.Enum
bool有anyflags(这是T enum1,T enum2),其中T:struct,System.Enum
尽管.net会有效地允许这样的构造,尽管唯一阻止C#将it代码排除在外以显式查找这样的约束以禁止它们,但C#设计人员决定禁止这样的构造,而不是允许它们像.net解释它们那样(这意味着
HasAnyFlags
无法直接使用
t
执行任何它可以执行的操作