【发布时间】:2017-10-31 22:44:18
【问题描述】:
我是 C# 新手,周末尝试编写 SNTP 服务器。 在此开发过程中,我最终遇到了与此完全相同的问题:How to use generics to pass argument to a non-generic method?
这里重复的问题是:“如何使用泛型将参数传递给非泛型方法?”这个问题的关键答案是所讨论的非泛型方法没有接受对象的重载。
现在我的问题是一个后续问题:为什么泛型以这种方式实现?或者换句话说,为什么需要约束?
到目前为止,我的理解是泛型有助于保持编译时类型安全,这意味着编译器知道在编译时正在处理哪些类型。
为什么没有实现 C#(或者这个问题应该与 CLR 相关),以便编译器可以接受这样一个事实,即正在创建一个泛型类/方法,其中可以提供一个在所有情况。然后,当调用泛型类/方法时,编译器可以看到问题并抱怨当时。
这是技术限制吗?
似乎真的很遗憾,不能创建泛型方法来包装具有多个重载的非泛型方法。除非我选择将类型检查推迟到运行时,这是上述问题的解决方案,否则我将不得不用一套方法包装这个重载方法,每个签名一个,即使其中的代码看起来相同。这将是利用泛型方法的理想场所。
【问题讨论】:
-
那时就不是泛型了,而是动态类型。你会得到一个运行时错误。正是您不想想要发生的事情。您希望 编译器 告诉您您传递了错误的类型,以便您可以修复它。顺便说一句,您可以使用
dynamic作为泛型类型,失去所有类型检查的好处 -
听起来你在描述
dynamic。dynamic变量像泛型一样被类型检查,但在运行时,而不是编译时。你可能会做出这样的选择是有原因的。但是编译时安全是一个相当有用的工具。与所有事情一样,您根据所涉及的权衡做出选择。 -
不,我的问题与为什么编译器在调用相关泛型时不能静态确保类型兼容性,而不是通过约束来确保这一点(或者在我的情况下,“计算机说不”场景)。
-
dynamic就是这样做的。它在调用方法时检查类型,如果没有则抛出异常。 -
对于泛型,答案通常是“考虑到泛型类型
T可能既是值类型又是引用类型,并且我们必须提前知道生成/调用正确的通用实现”?编译器不愿意插入修正代码来使这种情况正常工作,因为 C# 设计者更喜欢“所见即所得”的方法来处理这些事情。