C# 我可以在一个泛型类型上放置多个可选约束,其中只需要强制一个约束吗?

C# 我可以在一个泛型类型上放置多个可选约束,其中只需要强制一个约束吗?,c#,generics,constraints,C#,Generics,Constraints,我想在下面的泛型类型上加上约束,尽管我不确定是否可以按照我所希望的方式来做 public interface IMyClass<in TA, in TB> { bool MyMethod<TX, TY>(TX argumentX, TY argumentY); } public class MyClass<TA, TB> : IMyClass<TA, TB> { public bool MyMethod<TX, TY>

我想在下面的泛型类型上加上约束,尽管我不确定是否可以按照我所希望的方式来做

public interface IMyClass<in TA, in TB>
{
    bool MyMethod<TX, TY>(TX argumentX, TY argumentY);
}

public class MyClass<TA, TB> : IMyClass<TA, TB>
{
    public bool MyMethod<TX, TY>(TX argumentX, IEnumerable<TY> argumentsY)
    {
        // DO STUFF
    }
}
公共接口IMyClass
{
bool-MyMethod(TX-argumentX,TY-argumentY);
}
公共类MyClass:IMyClass
{
公共布尔MyMethod(TX argumentX、IEnumerable argumentsY)
{
//做事
}
}
类型TX和TY表示TA和TB,但需要可互换(这就是为什么我不能在不复制代码的情况下在方法中使用TA和TB)。这就是约束的作用方式:

  • TX必须与TA或TB的类型相同
  • TY必须与TA或TB的类型相同
  • 如果TX与TA的类型相同,则TY必须与TB(和v.v.)的类型相同

有没有一种方法可以在设计时使用通用约束强制执行此操作,或者我必须使用异常来实现它以在运行时失败?

简而言之,没有,通用约束是可加的,不能基于布尔逻辑打开或关闭。在这些类型的约束条件下,你究竟能做些什么,这是非常值得怀疑的。

不是直接的,但你可以用两种重载方法来解决这个问题

public class MyClass<TA, TB> : IMyClass<TA, TB>
{
    public bool MyMethod(TA argumentX, TB argumentY)
    {
        string argX = SpecialPreFormatterForTA(argumentX);
        string argY = SpecialPreFormatterForTB(argumentY);
        return MyMethodCommon(argX, argY);
    }

    public bool MyMethod(TB argumentX, TA argumentY)
    {
        string argX = SpecialPreFormatterForTB(argumentX);
        string argY = SpecialPreFormatterForTA(argumentY);
        return MyMethodCommon(argX, argY);
    }

    private bool MyMethodCommon(string argX, string argY)
    {
        // DO STUFF
    }
}
公共类MyClass:IMyClass
{
公共布尔MyMethod(TA argumentX、TB argumentY)
{
字符串argX=SpecialPreFormatterForTA(argumentX);
字符串argY=SpecialPreFormatterForTB(argumentY);
返回MyMethodCommon(argX,argY);
}
公共布尔MyMethod(TB argumentX、TA argumentY)
{
字符串argX=SpecialPreFormatterForTB(argumentX);
字符串argY=SpecialPreFormatterForTA(argumentY);
返回MyMethodCommon(argX,argY);
}
私有布尔MyMethodCommon(字符串argX,字符串argY)
{
//做事
}
}

我对代码做了一些修改和假设,以帮助证明这一点。您可以在每个重载方法中执行您需要执行的任何特定格式化,然后调用,然后您可以让两个函数调用第三个函数,该函数不关心两个原始参数的类型,以减少代码重复使用。

当我为这个问题简化代码时,我犯了一个错误-第二个方法参数实际上是一个集合(请参见编辑)。我需要迭代argumentsY(并且需要能够同时使用TA类型和TB类型)。我可以重载该方法,但是没有可以提取到公共方法中的代码(已经完成)。我被困在“不要重复你自己”规则和干净、清晰的代码之间。@yelxe TA和TB是否都实现了一个共同的基础或接口?如果有,问题是可以解决的。其中一种类型将是ORM模型对象,而另一种类型将是WCF数据传输对象。我能指望的唯一共同点是ObjId。如果我为所有模型和DTO设置了一个抽象类或接口,它不会将使用限制在我在使用过程中指定的特定模型和DTO上。请看,这就是为什么您应该提供所有详细信息的原因,这听起来是一项非常适合我的工作。它可以为您将ORM对象转换为DTO对象。我担心这一点。我可能需要采取不同的方法。为了回答您的not问题,我想用两种不同的方式(A、B和B、A)调用这个方法,而不需要重复代码,也不需要用反转类型实例化对象两次。