c# - C# 中的多态性、重载和泛型

标签 c# generics polymorphism overloading

class Poly
    {
    public static void WriteVal(int i) { System.Console.Write("{0}\n", i); }
    public static void WriteVal(string s) { System.Console.Write("{0}\n", s); }
    }

class GenWriter<T>
    {
        public static void Write(T x) { Poly.WriteVal(x); }
    }

为什么在 C# 中不接受无辜的(对于 C++ 程序员)方法 Write?

您可以看到编译器尝试将参数类型 T 与具体重载相匹配 before 实例化:

错误 3 The best overloaded method match for 'TestGenericPolyMorph.Poly.WriteVal(int)' has some invalid arguments

当然。目的不是像上面那样使用静态方法,目的是创建一个具有多态行为的包装器。 注意:我使用的是 VS 2010。

请注意,所有需要的信息都在编译时可用。再次强调:问题是验证是在模板实例化之前执行的。

讨论后补充:

嗯,可能是我没有正确强调这一点。 问题不仅涉及泛型和模板之间的区别,还涉及以下问题的解决方案:给定一组针对不同类型的重载,我想生成一组为这些类型提供虚拟方法(多态性)的包装类。 在运行时解析虚拟方法的代价很小,并且不会影响性能。这就是 C++ 模板派上用场的地方。显然,dynamic 的运行时类型解析的开销是完全不同的。 所以,问题是是否可以将现有的重载转换为多态而不复制代码并且不付出性能损失(例如,我不确定与尝试“切换”相比,dynamic 我获得了什么转换除了更好的语法)。

到目前为止,我看到的解决方案之一是生成/发出代码(原文如此!),即自动执行此操作而不是剪切和粘贴。

因此,我们不使用 C++ 模板处理,而是简单地手动执行或重新发明宏/模板处理器。

还有更好的吗?

最佳答案

简答:

C# 泛型不是 C++ 模板;尽管它们的语法相似,但它们却大不相同。模板是在编译时构建的,每次实例化一次,并且模板化代码必须对仅实际提供的模板参数是正确的。模板在每次实例化时执行一次重载解析和类型分析等任务;它们基本上是源代码文本 的智能“搜索和替换”机制。

C# 泛型是真正的泛型;对于任何可能的类型参数,它们必须是正确的。泛型代码分析一次,重载解析一次,等等。

长答案:这是一个副本

What are the differences between Generics in C# and Java... and Templates in C++?

有关详细信息,请参阅此处的长答案。

另请参阅我关于该主题的文章:

http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx

关于c# - C# 中的多态性、重载和泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8508896/

相关文章:

java - 如何找到桥接方法的声明方法?

ios - 将参数传递给实现协议(protocol)并快速扩展类的方法

python - Flask 基于类的 View ——多态性

java - 如何从父类获取子类的值

java - 非通用子类继承(实现)通用父类(super class)(接口(interface))

c# - 根据另一个数组中指定的索引从数组中选择元素c#

C#/.NET 不是通用 LinkedList 存在吗?

c# - 从另一个表单打开表单收到错误C#

c# - 使用 linq 将一对多关系转换为查找

c# - 引用我自己的类型的最佳方式