参数约束 - 调用约束类型的调用方法?

bud*_*ble 0 c# generics

我有一个带泛型参数的方法:

internal void DoSomething<T>(T workWithThis)
{
}
Run Code Online (Sandbox Code Playgroud)

我现在想要限制此方法只接受继承我想指定的几个接口之一的参数.但是我还没有找到办法.我想要的是这样的:

internal void DoSomething<T>(T workWithThis) where T : ISomething | ISomethingElse
{
}
Run Code Online (Sandbox Code Playgroud)

显然这不起作用,所以我尝试用静态方法来检查T的类型:

public static bool CheckType(Type t)
{
return */check here*/
}

internal void DoSomething<T>(T workWithThis) where T : CheckType(typeof(T))
{
}
Run Code Online (Sandbox Code Playgroud)

显然,这也无济于事.问题是为什么?为什么编译器阻止我这样做,根据我的理解,它没有理由不能工作

Jon*_*eet 5

为什么编译器阻止我这样做,根据我的理解,它没有理由不能工作

编译器阻止您执行此操作,因为您尝试执行C#作为语言不支持的操作.您尝试使用的语法不符合C#规范第10.1.5节中的产品.

C#作为一种语言根本不支持您需要的方案.

至于为什么语言不允许这种灵活性 - 这归结为以下的正常平衡行为:

  • 有多少开发人员可以从中受益多少
  • 其他开发人员理解更复杂语言的额外负担
  • 资源(主要在Microsoft内部)需要设计语言功能,实现和测试它

哦,当然这不只是C# - CLR也必须支持这样的限制,它至少会鼓励其他CLR语言理解它.

我建议你通过两种不同的方法解决这个问题.请注意,它们不能仅仅是泛型方法的重载,因为重载只能通过泛型类型约束来区分.如果你不介意拳击实现接口的值类型,你可以重载:

internal void DoSomething(ISomething something)
{
}

internal void DoSomething(ISomethingElse somethingElse)
{
}
Run Code Online (Sandbox Code Playgroud)

...虽然然后如果传入一个表达式是实现两个接口的类型,那么最终会出现过载歧义.

或者,只需给这两种方法命名不同.

  • @buddybubble:有7个重载*通常*表明设计可以改进开始,例如,具有所有这些其他接口扩展的单个接口.没有更多上下文就很难说更多,但你需要接受C#只是不支持"其中一个接口"的类型参数约束. (2认同)