当前位置: 首页 > 编程语言 > C#

你能用隐式转换满足泛型约束吗?分享

时间:2023-04-10 23:54:58 C#

你能用隐式转换满足泛型约束吗?给定以下类型:classA{}classB{publicstaticimplicitoperatorA(Bme){returnnewA();}}classTestwhereT:A{}我试过varb=newTest();并预计它会失败,它确实失败了。但错误消息是类型“B”不能用作泛型类型或方法“Test”中的类型参数“T”。没有从“B”到“A”的隐式引用转换。但是有一个从B到A的隐式引用转换。这只是奇怪的消息吗?AdamRobinson的回答表明没有隐式引用转换。该消息是正确的。请注意MSDN说:whereT:(baseclassname)-类型参数必须是指定的基类或派生自指定的基类。这就解释了为什么不允许,因为B不会从A派生A。不,你想做的事情是不可能的。隐式引用转换与隐式类型转换不同。您的代码定义了一个隐式类型转换:Bfoo=newB();酒吧=富;但请注意foo和bar现在包含不同的引用。隐式类型转换创建了一个新的A实例,它(按照惯例)在逻辑上应该等同于foo。但关键是它是一个不同的参考。引用转换将是引用本身不改变的地方,这意味着所讨论的类型必须继承(对于类)或实现(对于接口)所讨论的类型。如果我这样做:classA{}classB:A{}那么我上面的代码现在将在foo和bar中持有相同的引用。这就是隐式引用转换的意思。相反,显式引用转换将是向下转换,如下所示:Afoo=newB();Bbar=(B)foo;同样,引用是相同的,但转换是明确的。因此,简而言之,MSDN文档更清晰但不够精确。这是不可能的。隐式转换与类型等价不同。仅仅因为一种类型可以转换为另一种类型并不意味着它是第二种类型的特定形式。因此,它不适用于通用约束。这是完全有道理的——想想编译器会在下面做什么:classA{publicvoidFoo();}classB{publicstaticimplicitoperatorA(Bme){returnnewA();现在,假设你有:publicvoidBar(Tobj)whereT:A{obj.Foo();obj.Foo();obj.Foo();为了使它与转换一起工作(即:允许调用Bar(newB()))——你必须在该方法中构造一个新的对象实例,因为Foo没有在B上定义。这将是非常意外的,并且可能导致一些很难找到的错误。上面是不是每次方法调用都要进行转换操作呢?它应该发生一次,并且编译器会采取一些技巧使其工作吗?虽然可以想象如何处理这个问题,但没有一种方法是确定的......其他人已经涵盖了它,但我想我会粘贴一些规范内容有效负载的完整列表在c#语言规范的第6.1.6节中章节。关键部分是最后一段所说的:隐式或显式引用转换永远不会改变被转换对象的引用标识。换句话说,虽然引用转换可能会改变引用的类型,但它永远不会改变它所引用的对象的类型或值。完整的转换列表如下:隐式引用转换是:从任何数组类型到System.Array及其实现的接口。从一维数组类型S[]到System.Collections.Generic.IList及其基接口,前提是存在从S到T的隐式标识或引用转换。从任何委托类型到System.Delegate及其实现的接口.从空文字到任何引用类型。从任何引用类型到引用类型T,如果它具有隐式标识或到引用类型T0的引用转换,则T0具有到T的标识转换。从任何引用类型到接口或委托类型T,如果它具有隐式标识或对接口或委托类型T0和T0的引用转换可转换为T(第13.1.3.2节)。已知为引用类型的类型涉及参数的隐式转换。有关涉及类型参数的隐式转换的更多详细信息,请参见第6.1.10节。在您的示例代码中,B不是从A派生A。试试classB:A{publicstaticimplicitoperatorA(Bme){returnnewA();不,这不是一个奇怪的信息。“隐式引用转换”(规范第6.1.6节)与“用户定义的隐式转换”(第6.1.10节)不同,后者是您所拥有的。引用转换意味着您可以将对给定对象的引用从一种类型转换为另一种类型(“引用转换......永远不会改变被转换对象的引用标识”)。用户定义的隐式转换可以(像你的一样)返回一个新的不同对象。以上是C#学习教程:Canyouuseimplicitconversiontosatisfygenericsconstraints?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: