C#泛型是否支持类型签名约束?

8
C++ 模板的一个好处是你(隐式地)可以要求某种类型签名(例如,类型 T 需要有一个函数 x,该函数不带参数并返回 int)。C# 泛型是否支持类似的功能?
我知道基于基类或接口的约束,但这不是我要找的。
(作为一名学习 C# 的 C++ 程序员,我可能误认为这是你想要在 C# 中使用的功能。对此的任何评论也将受到赞赏...)

4
但是界面约束已经是一种相当好的表达方式,比如 T 实现了方法 X(),其匹配某个签名,你觉得呢? - Frédéric Hamidi
7个回答

6

除了您已经看到的约束条件(公平地说,这些条件涵盖了许多常见情况)以外,没有其他限制。以下是一些常见的解决方法:

  • dynamic,在4.0中可用
  • 使用反射或IL生成等手动鸭子类型

尽管这些方法都没有静态类型检查等功能。


动态可能是我能得到的最接近的。事实上,我经常把C++模板想象成一种“动态编译时语言”(这可能是一个除了我之外没有人能理解的短语 :) - Tobias Furuholm
@Tobias 我会选择“静态检查的鸭子类型” ;p(dynamic 暗示了运行时,但我知道你的意思) - Marc Gravell
突然间,所有人都能理解它了 :) - Tobias Furuholm

4
是的,可以通过接口实现。您可以定义一个通用对象,该对象必须实现特定接口的类型。在该接口中,您基本上会强制任何添加到该通用列表中的对象具有特定的签名。
无论您是否不需要这样做,这就是您实现它的方式。 :)

1
然而,这仍然不能涵盖所有选项 - 带参数的构造函数、运算符、静态方法等等... - Marc Gravell
@Marc 嗯,在这种情况下没有完美的解决方案 - 就像你在答案中提到的那样。 OP将不得不做出一些妥协来完成他的任务。而且他可能不需要你提到的任何东西。他希望他的通用类符合“不带参数并返回int的函数x”的要求。 - George Johnston
@Marc,我同意,并且在非默认构造函数上支持约束会很好。其他的不是那么重要,尤其是运算符 :) - Frédéric Hamidi
@Marc 但是这只是一个通用解决方案。他完全可以从适合自己需求的任何角度来解决问题 :) - George Johnston
这需要类型参数的类型符合泛型类的需求,而这有时并不是你想要的。(我并不是在解决特定问题,而是试图理解 C# 泛型提供的各种可能性)。 - Tobias Furuholm

3
不,这是不可能的。主要是由于C++模板和C#泛型之间的差异造成的:
当你编译C++模板时,生成的代码具有像vector<int>vector<string>这样的类型。这意味着编译器必须知道所有可能的类型参数,但这也意味着它可以检查它们是否正确。
当你编译C#泛型类型时,实际上只创建了一个通用类型:List<T>。因此,C#编译器在编译时不必知道所有可能的类型,这意味着你可以在二进制库中使用泛型类型,而这在C++中是不可能的。但这也意味着你无法检查所有类型。为了能够做到这一点,有一些约束条件,但它们不能像C++的编译时检查那样做一些事情,比如检查某些方法的存在(不使用接口或某个基类)或适当运算符的存在。
在C# 4中,你可以使用dynamic实现与此类模板相似的效果,但这没有编译时检查,这意味着你会失去安全性——你可以放入一个没有适当成员的类型,直到你在运行时到达那行代码才会发现。

1
不。这就是“接口”的作用。创建一个定义了你想要在类型约束中强制执行的契约的接口。然后在约束中指定它。

0

在 .Net 中,你可以对泛型设置 5 种类型的约束:

  1. 派生约束指定了类型参数的升级关系。
  2. 接口约束是由类型参数实现的接口。
  3. 值类型约束将类型参数限制为值类型。
  4. 引用类型约束将类型参数限制为引用类型。
  5. 构造函数约束要求类型参数具有默认或无参构造函数。

页面显示更多信息。


我知道基于基类或接口的约束,但这不是我要找的。 - Marc Gravell

0

在 c# 中不支持。就像你说的,最接近的东西需要让类实现一个公共接口。

你可以试着用反射来模仿这种行为,通过查找方法签名来实现,但那是一个运行时约束,而不是编译时约束。


0

不,C#没有这样的限制。

如您所知,泛型约束只能强制执行基类或接口的继承,或者几个其他约束(构造函数约束new(),引用类型约束class,值类型约束struct)。

您可以使用委托来实现所需的行为,并且有许多通用委托可用。
例如,Func<int>是一个不带参数并返回int的委托。 Func<string, DateTime, int>接受一个stringDateTime并返回int,等等......


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接