C#中的多态,重载和泛型

Yur*_* S. 12 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); }
    }
Run Code Online (Sandbox Code Playgroud)

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

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

错误3'TestGenericPolyMorph.Poly.WriteVal(int)'的最佳重载方法匹配有一些无效的参数

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

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

讨论后增加:

好吧,可能我没有正确地强调这一点.问题不仅在于泛型和模板之间的区别,还在于解决以下问题:给定一组解决不同类型的重载,我想生成一组包装类,为这些类型提供虚方法(多态).运行时虚拟方法的解析价格很小,并没有达到性能.这是C++模板很方便的地方.显然,动态的运行时类型解析的开销是完全不同的.因此,问题是,是否可以在不复制代码的情况下将现有的重载转换为多态,并且不会牺牲性能损失(例如,我不确定动态与"switch"相比,除了更好的语法之外的"switch").

到目前为止我见过的解决方案之一是生成/发出代码(sic!),即不是自动剪切和粘贴.

因此,我们只需手动执行或仅重新创建宏/模板处理器,而不是C++模板处理.

还有什么更好的?

Eri*_*ert 27

简短回答:

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

C#泛型是真正的通用类型; 它们必须对任何可能的类型参数都是正确的.分析通用代码一次,重载分辨率完成一次,依此类推.

答案很长:这是重复的

C#和Java中的泛型与C++中的模板有什么区别?

请查看详细的长答案.

另见我关于这个主题的文章:

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

  • 很棒的答案...一如既往:) (2认同)

Tud*_*dor 5

为什么你不能简单地写:

public static void Write<T>(T x) { System.Console.Write("{0}\n", x); }
Run Code Online (Sandbox Code Playgroud)