繁体   English   中英

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

[英]Polymorphism, overloads and generics in C#

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#中是不可接受的?

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

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

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

讨论后增加:

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

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

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

还有什么更好的?

简短回答:

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

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

答案很长:这是重复的

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

请查看详细的长答案。

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

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

为什么你不能简单地写:

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

C ++和C#泛型不同( http://msdn.microsoft.com/en-us/library/c6cyy67b(v=VS.80).aspx ,在您最喜欢的搜索网站上搜索“c#c ++泛型差异”)

简短:C#编译器必须通过查看类本身来创建具有所有类型匹配的完整GenWriter<T>类。 所以它不知道T是否只是int / string或任何其他类型。

C ++编译器通过查看通用GenWriter<int>和声明GenWriter<T>实例化来创建实际类,然后为该特定实例创建类。

如果有人要调用GenWriter(5.0) ,这将被推断为GenWriter<double>(5.0) ,并且Write(T x)内的方法调用将变为:

public static void Write(double x) { Poly.WriteVal(x); }

WriteVal没有超载,需要加倍。 编译器通知您没有WriteVal有效重载。

C#泛型和C ++模板并不完全等效。

你不能在C#中这样做,因为编译器不知道编译时x的类型是什么。

如果不了解T的实际类型,编译器会担心您可能打算执行自定义转换。 最简单的解决方案是使用as运算符,因为它无法执行自定义转换,因此无法实现。

更普遍的解决方案是首先投射到对象。 这是有帮助的,因为拳击拆箱问题:

return (int)(object) x;

请记住,C#Generics不像C ++模板。 C ++模板是分别为每种类型编译的代码片段。 虽然C#泛型是以汇编方式编译的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM